feat(physics): wire physx sdk into build

This commit is contained in:
2026-04-15 12:22:15 +08:00
parent 5bf258df6d
commit 31f40e2cbb
2044 changed files with 752623 additions and 1 deletions

View File

@@ -0,0 +1,119 @@
// 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/PxVehicleParams.h"
#include "vehicle2/PxVehicleComponent.h"
#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h"
#include "vehicle2/suspension/PxVehicleSuspensionParams.h"
#include "vehicle2/suspension/PxVehicleSuspensionStates.h"
#include "PxVehiclePhysXConstraintFunctions.h"
#include "PxVehiclePhysXConstraintHelpers.h"
#include "PxVehiclePhysXConstraintStates.h"
#include "PxVehiclePhysXConstraintParams.h"
#include "common/PxProfileZone.h"
#if !PX_DOXYGEN
namespace physx
{
namespace vehicle2
{
#endif
class PxVehiclePhysXConstraintComponent : public PxVehicleComponent
{
public:
PxVehiclePhysXConstraintComponent() : PxVehicleComponent() {}
virtual ~PxVehiclePhysXConstraintComponent() {}
virtual void getDataForPhysXConstraintComponent(
const PxVehicleAxleDescription*& axleDescription,
const PxVehicleRigidBodyState*& rigidBodyState,
PxVehicleArrayData<const PxVehicleSuspensionParams>& suspensionParams,
PxVehicleArrayData<const PxVehiclePhysXSuspensionLimitConstraintParams>& suspensionLimitParams,
PxVehicleArrayData<const PxVehicleSuspensionState>& suspensionStates,
PxVehicleArrayData<const PxVehicleSuspensionComplianceState>& suspensionComplianceStates,
PxVehicleArrayData<const PxVehicleRoadGeometryState>& wheelRoadGeomStates,
PxVehicleArrayData<const PxVehicleTireDirectionState>& tireDirectionStates,
PxVehicleArrayData<const PxVehicleTireStickyState>& tireStickyStates,
PxVehiclePhysXConstraints*& constraints) = 0;
virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context)
{
PX_UNUSED(dt);
PX_UNUSED(context);
PX_PROFILE_ZONE("PxVehiclePhysXConstraintComponent::update", 0);
const PxVehicleAxleDescription* axleDescription;
const PxVehicleRigidBodyState* rigidBodyState;
PxVehicleArrayData<const PxVehicleSuspensionParams> suspensionParams;
PxVehicleArrayData<const PxVehiclePhysXSuspensionLimitConstraintParams> suspensionLimitParams;
PxVehicleArrayData<const PxVehicleSuspensionState> suspensionStates;
PxVehicleArrayData<const PxVehicleSuspensionComplianceState> suspensionComplianceStates;
PxVehicleArrayData<const PxVehicleRoadGeometryState> wheelRoadGeomStates;
PxVehicleArrayData<const PxVehicleTireDirectionState> tireDirectionStates;
PxVehicleArrayData<const PxVehicleTireStickyState> tireStickyStates;
PxVehiclePhysXConstraints* constraints;
getDataForPhysXConstraintComponent(axleDescription, rigidBodyState,
suspensionParams, suspensionLimitParams, suspensionStates, suspensionComplianceStates,
wheelRoadGeomStates, tireDirectionStates, tireStickyStates,
constraints);
PxVehicleConstraintsDirtyStateUpdate(*constraints);
for (PxU32 i = 0; i < axleDescription->nbWheels; i++)
{
const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i];
PxVehiclePhysXConstraintStatesUpdate(
suspensionParams[wheelId], suspensionLimitParams[wheelId],
suspensionStates[wheelId], suspensionComplianceStates[wheelId],
wheelRoadGeomStates[wheelId].plane.n,
context.tireStickyParams.stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].damping,
context.tireStickyParams.stickyParams[PxVehicleTireDirectionModes::eLATERAL].damping,
tireDirectionStates[wheelId], tireStickyStates[wheelId],
*rigidBodyState,
constraints->constraintStates[wheelId]);
}
return true;
}
};
#if !PX_DOXYGEN
} // namespace vehicle2
} // namespace physx
#endif

View File

@@ -0,0 +1,88 @@
// 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 "foundation/PxVec3.h"
#if !PX_DOXYGEN
namespace physx
{
namespace vehicle2
{
#endif
struct PxVehicleSuspensionParams;
struct PxVehiclePhysXSuspensionLimitConstraintParams;
struct PxVehicleSuspensionState;
struct PxVehicleSuspensionComplianceState;
struct PxVehicleTireDirectionState;
struct PxVehicleTireStickyState;
struct PxVehicleRigidBodyState;
struct PxVehiclePhysXConstraintState;
/**
\brief Read constraint data from the vehicle's internal state for a single wheel and write it to a
structure that will be read by the associated PxScene and used to impose the constraints during the next
PxScene::simulate() step.
\param[in] suspensionParams describes the suspension frame.
\param[in] suspensionLimitParams describes the restitution value applied to any constraint triggered by
the suspension travel limit.
\param[in] suspensionState describes the excess suspension compression beyond the suspension travel limit that will be
resolved with a constraint.
\param[in] suspensionComplianceState describes the effect of suspension compliance on the effective application point
of the suspension force.
\param[in] groundPlaneNormal The normal direction of the ground plane the wheel is driving on. A normalized vector is
expected.
\param[in] tireStickyDampingLong The damping coefficient to use in the constraint to approach a zero target velocity
along the longitudinal tire axis.
\param[in] tireStickyDampingLat Same concept as tireStickyDampingLong but for the lateral tire axis.
\param[in] tireDirectionState describes the longitudinal and lateral directions of the tire in the world frame.
\param[in] tireStickyState describes the low speed state of the tire in the longitudinal and lateral directions.
\param[in] rigidBodyState describes the pose of the rigid body.
\param[out] constraintState is the data structure that will be read by the associated PxScene in the next call to
PxScene::simulate().
\note Constraints include suspension constraints to account for suspension travel limit and sticky
tire constraints that bring the vehicle to rest at low longitudinal and lateral speed.
*/
void PxVehiclePhysXConstraintStatesUpdate
(const PxVehicleSuspensionParams& suspensionParams,
const PxVehiclePhysXSuspensionLimitConstraintParams& suspensionLimitParams,
const PxVehicleSuspensionState& suspensionState, const PxVehicleSuspensionComplianceState& suspensionComplianceState,
const PxVec3& groundPlaneNormal,
const PxReal tireStickyDampingLong, const PxReal tireStickyDampingLat,
const PxVehicleTireDirectionState& tireDirectionState, const PxVehicleTireStickyState& tireStickyState,
const PxVehicleRigidBodyState& rigidBodyState,
PxVehiclePhysXConstraintState& constraintState);
#if !PX_DOXYGEN
} // namespace vehicle2
} // namespace physx
#endif

View File

@@ -0,0 +1,88 @@
// 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 "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
class PxPhysics;
class PxRigidBody;
namespace vehicle2
{
#endif
struct PxVehicleAxleDescription;
struct PxVehiclePhysXConstraints;
/**
\brief Instantiate the PhysX custom constraints.
Custom constraints will resolve excess suspension compression and velocity constraints that serve as
a replacement low speed tire model.
\param[in] axleDescription describes the axles of the vehicle and the wheels on each axle.
\param[in] physics is a PxPhysics instance.
\param[in] physxActor is the vehicle's PhysX representation as a PxRigidBody
\param[in] vehicleConstraints is a wrapper class that holds pointers to PhysX objects required to implement the custom constraint.
*/
void PxVehicleConstraintsCreate
(const PxVehicleAxleDescription& axleDescription,
PxPhysics& physics, PxRigidBody& physxActor,
PxVehiclePhysXConstraints& vehicleConstraints);
/**
\brief To ensure the constraints are processed by the PhysX scene they are marked as dirty prior to each simulate step.
\param[in] vehicleConstraints is a wrapper class that holds pointers to PhysX objects required to implement the custom constraint.
\see PxVehicleConstraintsCreate
*/
void PxVehicleConstraintsDirtyStateUpdate
(PxVehiclePhysXConstraints& vehicleConstraints);
/**
\brief Destroy the PhysX custom constraints.
\param[in,out] vehicleConstraints describes the PhysX custom constraints to be released.
\see PxVehicleConstraintsCreate
*/
void PxVehicleConstraintsDestroy
(PxVehiclePhysXConstraints& vehicleConstraints);
#if !PX_DOXYGEN
} // namespace vehicle2
} // namespace physx
#endif

View File

@@ -0,0 +1,106 @@
// 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 "foundation/PxFoundation.h"
#if !PX_DOXYGEN
namespace physx
{
namespace vehicle2
{
#endif
struct PxVehicleFrame;
struct PxVehicleScale;
/**
\brief A description of the PhysX models employed to resolve suspension limit constraints.
\see PxVehiclePhysXConstraintState
*/
struct PxVehiclePhysXSuspensionLimitConstraintParams
{
/**
\brief restitution is used by the restitution model used to generate a target velocity when resolving suspension limit
constraints.
\note A value of 0.0 means that the restitution model is not employed.
\note Restitution has no effect if directionForSuspensionLimitConstraint has value Enum::eNONE.
\see Px1DConstraintFlag::eRESTITUTION
\see Px1DConstraint::RestitutionModifiers::restitution
*/
PxReal restitution;
/**
\brief Set the direction to apply a constraint impulse when the suspension cannot place the wheel on the ground
and simultaneously respect the limits of suspension travel. The choices are to push along the ground normal to resolve the
geometric error or to push along the suspension direction. The former choice can be thought of as mimicing a force applied
by the tire's contact with the ground, while the latter can be thought of as mimicing a force arising from a suspension limit spring.
When the ground normal and the suspension direction are approximately aligned, both do an equivalent job of maintaining the wheel above
the ground. When the vehicle is on its side, eSUSPENSION does a better job of keeping the wheels above
the ground but comes at the cost of an unnaturally strong torque that can lead to unwanted self-righting behaviour.
eROAD_GEOMETRY_NORMAL is a good choice to avoid self-righting behaviour and still do a reasonable job at maintaining
the wheel above the ground in the event that the vehicle is tending towards a roll onto its side.
eNONE should be chosen if it is desired that no extra impulse is applied when the suspension alone cannot keep the wheels above
the ground plane.
*/
enum DirectionSpecifier
{
eSUSPENSION,
eROAD_GEOMETRY_NORMAL,
eNONE
};
DirectionSpecifier directionForSuspensionLimitConstraint;
PX_FORCE_INLINE PxVehiclePhysXSuspensionLimitConstraintParams transformAndScale(
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
{
PX_UNUSED(srcFrame);
PX_UNUSED(trgFrame);
PX_UNUSED(srcScale);
PX_UNUSED(trgScale);
return *this;
}
PX_FORCE_INLINE bool isValid() const
{
PX_CHECK_AND_RETURN_VAL(
PxVehiclePhysXSuspensionLimitConstraintParams::eSUSPENSION == directionForSuspensionLimitConstraint ||
PxVehiclePhysXSuspensionLimitConstraintParams::eROAD_GEOMETRY_NORMAL == directionForSuspensionLimitConstraint ||
PxVehiclePhysXSuspensionLimitConstraintParams::eNONE == directionForSuspensionLimitConstraint, "PxVehiclePhysXSuspensionLimitConstraintParams.directionForSuspensionLimitConstraint must have legal value", false);
PX_CHECK_AND_RETURN_VAL(restitution >= 0.0f && restitution <= 1.0f, "PxVehiclePhysXSuspensionLimitConstraintParams.restitution must be in range [0, 1]", false);
return true;
}
};
#if !PX_DOXYGEN
} // namespace vehicle2
} // namespace physx
#endif

View File

@@ -0,0 +1,353 @@
// 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 "foundation/PxAssert.h"
#include "foundation/PxTransform.h"
#include "extensions/PxConstraintExt.h"
#include "vehicle2/PxVehicleLimits.h"
#include "vehicle2/tire/PxVehicleTireStates.h"
#include "PxConstraint.h"
#include "PxConstraintDesc.h"
#if !PX_DOXYGEN
namespace physx
{
class PxConstraint;
namespace vehicle2
{
#endif
/**
\brief A description of the number of PxConstraintConnector instances per vehicle required to maintain suspension limit
and sticky tire instances.
*/
struct PxVehiclePhysXConstraintLimits
{
enum Enum
{
eNB_DOFS_PER_PXCONSTRAINT = 12,
eNB_DOFS_PER_WHEEL = 3,
eNB_WHEELS_PER_PXCONSTRAINT = eNB_DOFS_PER_PXCONSTRAINT / eNB_DOFS_PER_WHEEL,
eNB_CONSTRAINTS_PER_VEHICLE = (PxVehicleLimits::eMAX_NB_WHEELS + (eNB_WHEELS_PER_PXCONSTRAINT - 1)) / (eNB_WHEELS_PER_PXCONSTRAINT)
};
};
/**
\brief PxVehiclePhysXConstraintState is a data structure used to write
constraint data to the internal state of the associated PxScene.
\see Px1dConstraint
*/
struct PxVehiclePhysXConstraintState
{
/**
\brief a boolean describing whether to trigger a low speed constraint along the tire longitudinal and lateral directions.
*/
bool tireActiveStatus[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS];
/**
\brief linear component of velocity jacobian in world space for the tire's longitudinal and lateral directions.
*/
PxVec3 tireLinears[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS];
/**
\brief angular component of velocity jacobian in world space for the tire's longitudinal and lateral directions.
*/
PxVec3 tireAngulars[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS];
/**
\brief damping coefficient applied to the tire's longitudinal and lateral velocities.
The constraint sets a target velocity of 0 and the damping coefficient will impact the size of the
impulse applied to reach the target. Since damping acts as a stiffness with respect to the velocity,
too large a value can cause instabilities.
*/
PxReal tireDamping[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS];
/**
\brief a boolean describing whether to trigger a suspension limit constraint.
*/
bool suspActiveStatus;
/**
\brief linear component of velocity jacobian in the world frame.
*/
PxVec3 suspLinear;
/**
\brief angular component of velocity jacobian in the world frame.
*/
PxVec3 suspAngular;
/**
\brief the excess suspension compression to be resolved by the constraint that cannot be resolved due to the travel limit
of the suspension spring.
\note The expected error value is the excess suspension compression projected onto the ground plane normal and should have
a negative sign.
*/
PxReal suspGeometricError;
/**
\brief restitution value of the restitution model used to generate a target velocity that will resolve the geometric error.
\note A value of 0.0 means that the restitution model is not employed.
\see Px1DConstraintFlag::eRESTITUTION
\see Px1DConstraint::RestitutionModifiers::restitution
*/
PxReal restitution;
PX_FORCE_INLINE void setToDefault()
{
PxMemZero(this, sizeof(PxVehiclePhysXConstraintState));
}
};
//TAG:solverprepshader
PX_FORCE_INLINE PxU32 vehicleConstraintSolverPrep
(Px1DConstraint* constraints,
PxVec3p& body0WorldOffset,
PxU32 maxConstraints,
PxConstraintInvMassScale&,
const void* constantBlock,
const PxTransform& bodyAToWorld,
const PxTransform& bodyBToWorld,
bool,
PxVec3p& cA2w, PxVec3p& cB2w)
{
PX_UNUSED(maxConstraints);
PX_UNUSED(body0WorldOffset);
PX_UNUSED(bodyBToWorld);
PX_ASSERT(bodyAToWorld.isValid()); PX_ASSERT(bodyBToWorld.isValid());
const PxVehiclePhysXConstraintState* data = static_cast<const PxVehiclePhysXConstraintState*>(constantBlock);
PxU32 numActive = 0;
//KS - the TGS solver will use raXn to try to add to the angular part of the linear constraints.
//We overcome this by setting the ra and rb offsets to be 0.
cA2w = bodyAToWorld.p;
cB2w = bodyBToWorld.p;
// note: this is only needed for PxSolverType::eTGS and even then it should not have an effect as
// long as a constraint raises Px1DConstraintFlag::eANGULAR_CONSTRAINT
//Susp limit constraints.
for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++)
{
if (data[i].suspActiveStatus)
{
// Going beyond max suspension compression should be treated similar to rigid body contacts.
// Thus setting up constraints that try to emulate such contacts.
//
// linear l = contact normal = n
// angular a = suspension force application offset x contact normal = cross(r, n)
//
// velocity at contact:
// vl: part from linear vehicle velocity v
// vl = dot(n, v) = dot(l, v)
//
// va: part from angular vehicle velocity w
// va = dot(n, cross(w, r)) = dot(w, cross(r, n)) = dot(w, a)
//
// ve: part from excess suspension compression
// ve = (geomError / dt) (note: geomError is expected to be negative here)
//
// velocity target vt = vl + va + ve
// => should become 0 by applying positive impulse along l. If vt is positive,
// nothing will happen as a negative impulse would have to be applied (but
// min impulse is set to 0). If vt is negative, a positive impulse will get
// applied to push vt towards 0.
//
Px1DConstraint& p = constraints[numActive];
p.linear0 = data[i].suspLinear;
p.angular0 = data[i].suspAngular;
p.geometricError = data[i].suspGeometricError;
p.linear1 = PxVec3(0);
p.angular1 = PxVec3(0);
p.minImpulse = 0;
p.maxImpulse = FLT_MAX;
p.velocityTarget = 0;
p.solveHint = PxConstraintSolveHint::eINEQUALITY;
// note: this is only needed for PxSolverType::eTGS to not have the angular part
// be modified based on the linear part during substeps. Basically, it will
// disable the constraint re-projection etc. to emulate PxSolverType::ePGS.
p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT;
if (data[i].restitution > 0.0f)
{
p.flags |= Px1DConstraintFlag::eRESTITUTION;
p.mods.bounce.restitution = data[i].restitution;
p.mods.bounce.velocityThreshold = -FLT_MAX;
}
numActive++;
}
}
//Sticky tire friction constraints.
for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++)
{
if (data[i].tireActiveStatus[PxVehicleTireDirectionModes::eLONGITUDINAL])
{
Px1DConstraint& p = constraints[numActive];
p.linear0 = data[i].tireLinears[PxVehicleTireDirectionModes::eLONGITUDINAL];
p.angular0 = data[i].tireAngulars[PxVehicleTireDirectionModes::eLONGITUDINAL];
p.geometricError = 0.0f;
p.linear1 = PxVec3(0);
p.angular1 = PxVec3(0);
p.minImpulse = -FLT_MAX;
p.maxImpulse = FLT_MAX;
p.velocityTarget = 0.0f;
p.mods.spring.damping = data[i].tireDamping[PxVehicleTireDirectionModes::eLONGITUDINAL];
// note: no stiffness specified as this will have no effect with geometricError=0
p.flags = Px1DConstraintFlag::eSPRING | Px1DConstraintFlag::eACCELERATION_SPRING;
p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT; // see explanation of same flag usage further above
numActive++;
}
}
//Sticky tire friction constraints.
for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++)
{
if (data[i].tireActiveStatus[PxVehicleTireDirectionModes::eLATERAL])
{
Px1DConstraint& p = constraints[numActive];
p.linear0 = data[i].tireLinears[PxVehicleTireDirectionModes::eLATERAL];
p.angular0 = data[i].tireAngulars[PxVehicleTireDirectionModes::eLATERAL];
p.geometricError = 0.0f;
p.linear1 = PxVec3(0);
p.angular1 = PxVec3(0);
p.minImpulse = -FLT_MAX;
p.maxImpulse = FLT_MAX;
p.velocityTarget = 0.0f;
p.mods.spring.damping = data[i].tireDamping[PxVehicleTireDirectionModes::eLATERAL];
// note: no stiffness specified as this will have no effect with geometricError=0
p.flags = Px1DConstraintFlag::eSPRING | Px1DConstraintFlag::eACCELERATION_SPRING;
p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT; // see explanation of same flag usage further above
numActive++;
}
}
return numActive;
}
PX_FORCE_INLINE void visualiseVehicleConstraint
(PxConstraintVisualizer &viz,
const void* constantBlock,
const PxTransform& body0Transform,
const PxTransform& body1Transform,
PxU32 flags)
{
PX_UNUSED(&viz);
PX_UNUSED(constantBlock);
PX_UNUSED(body0Transform);
PX_UNUSED(body1Transform);
PX_UNUSED(flags);
PX_ASSERT(body0Transform.isValid());
PX_ASSERT(body1Transform.isValid());
}
class PxVehicleConstraintConnector : public PxConstraintConnector
{
public:
PxVehicleConstraintConnector() : mVehicleConstraintState(NULL) {}
PxVehicleConstraintConnector(PxVehiclePhysXConstraintState* vehicleConstraintState) : mVehicleConstraintState(vehicleConstraintState) {}
~PxVehicleConstraintConnector() {}
void setConstraintState(PxVehiclePhysXConstraintState* constraintState) { mVehicleConstraintState = constraintState; }
virtual void* prepareData() { return mVehicleConstraintState; }
virtual const void* getConstantBlock() const { return mVehicleConstraintState; }
virtual PxConstraintSolverPrep getPrep() const { return vehicleConstraintSolverPrep; }
//Is this necessary if physx no longer supports double-buffering?
virtual void onConstraintRelease() { }
//Can be empty functions.
virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection, const PxConstraint* c, PxPvdUpdateType::Enum updateType) const
{
PX_UNUSED(pvdConnection);
PX_UNUSED(c);
PX_UNUSED(updateType);
return true;
}
virtual void updateOmniPvdProperties() const { }
virtual void onComShift(PxU32 actor) { PX_UNUSED(actor); }
virtual void onOriginShift(const PxVec3& shift) { PX_UNUSED(shift); }
virtual void* getExternalReference(PxU32& typeID) { typeID = PxConstraintExtIDs::eVEHICLE_JOINT; return this; }
virtual PxBase* getSerializable() { return NULL; }
private:
PxVehiclePhysXConstraintState* mVehicleConstraintState;
};
/**
\brief A mapping between constraint state data and the associated PxConstraint instances.
*/
struct PxVehiclePhysXConstraints
{
/**
\brief PxVehiclePhysXConstraintComponent writes to the constraintStates array and a
callback invoked by PxScene::simulate() reads a portion from it for a block of wheels
and writes that portion to an associated PxConstraint instance.
*/
PxVehiclePhysXConstraintState constraintStates[PxVehicleLimits::eMAX_NB_WHEELS];
/**
\brief PxVehiclePhysXConstraintComponent writes to the constraintStates array and a
callback invoked by PxScene::simulate() reads a portion from it for a block of wheels
and writes that portion to an associated PxConstraint instance.
*/
PxConstraint* constraints[PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE];
/**
\brief A constraint connector is necessary to connect each PxConstraint to a portion of the constraintStates array.
*/
PxVehicleConstraintConnector* constraintConnectors[PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE];
PX_FORCE_INLINE void setToDefault()
{
for (PxU32 i = 0; i < PxVehicleLimits::eMAX_NB_WHEELS; i++)
{
constraintStates[i].setToDefault();
}
for(PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE; i++)
{
constraints[i] = NULL;
constraintConnectors[i] = NULL;
}
}
};
#if !PX_DOXYGEN
} // namespace vehicle2
} // namespace physx
#endif