Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Vehicle/Wheel.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Body/Body.h>7#include <Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h>8#include <Jolt/ObjectStream/SerializableObject.h>9#include <Jolt/Core/StreamIn.h>10#include <Jolt/Core/StreamOut.h>1112JPH_NAMESPACE_BEGIN1314class VehicleConstraint;1516/// Base class for wheel settings, each VehicleController can implement a derived class of this17class JPH_EXPORT WheelSettings : public SerializableObject, public RefTarget<WheelSettings>18{19JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, WheelSettings)2021public:22/// Saves the contents in binary form to inStream.23virtual void SaveBinaryState(StreamOut &inStream) const;2425/// Restores the contents in binary form to inStream.26virtual void RestoreBinaryState(StreamIn &inStream);2728Vec3 mPosition { 0, 0, 0 }; ///< Attachment point of wheel suspension in local space of the body29Vec3 mSuspensionForcePoint { 0, 0, 0 }; ///< Where tire forces (suspension and traction) are applied, in local space of the body. A good default is the center of the wheel in its neutral pose. See mEnableSuspensionForcePoint.30Vec3 mSuspensionDirection { 0, -1, 0 }; ///< Direction of the suspension in local space of the body, should point down31Vec3 mSteeringAxis { 0, 1, 0 }; ///< Direction of the steering axis in local space of the body, should point up (e.g. for a bike would be -mSuspensionDirection)32Vec3 mWheelUp { 0, 1, 0 }; ///< Up direction when the wheel is in the neutral steering position (usually VehicleConstraintSettings::mUp but can be used to give the wheel camber or for a bike would be -mSuspensionDirection)33Vec3 mWheelForward { 0, 0, 1 }; ///< Forward direction when the wheel is in the neutral steering position (usually VehicleConstraintSettings::mForward but can be used to give the wheel toe, does not need to be perpendicular to mWheelUp)34float mSuspensionMinLength = 0.3f; ///< How long the suspension is in max raised position relative to the attachment point (m)35float mSuspensionMaxLength = 0.5f; ///< How long the suspension is in max droop position relative to the attachment point (m)36float mSuspensionPreloadLength = 0.0f; ///< The natural length (m) of the suspension spring is defined as mSuspensionMaxLength + mSuspensionPreloadLength. Can be used to preload the suspension as the spring is compressed by mSuspensionPreloadLength when the suspension is in max droop position. Note that this means when the vehicle touches the ground there is a discontinuity so it will also make the vehicle more bouncy as we're updating with discrete time steps.37SpringSettings mSuspensionSpring { ESpringMode::FrequencyAndDamping, 1.5f, 0.5f }; ///< Settings for the suspension spring38float mRadius = 0.3f; ///< Radius of the wheel (m)39float mWidth = 0.1f; ///< Width of the wheel (m)40bool mEnableSuspensionForcePoint = false; ///< Enables mSuspensionForcePoint, if disabled, the forces are applied at the collision contact point. This leads to a more accurate simulation when interacting with dynamic objects but makes the vehicle less stable. When setting this to true, all forces will be applied to a fixed point on the vehicle body.41};4243/// Base class for runtime data for a wheel, each VehicleController can implement a derived class of this44class JPH_EXPORT Wheel : public NonCopyable45{46public:47JPH_OVERRIDE_NEW_DELETE4849/// Constructor / destructor50explicit Wheel(const WheelSettings &inSettings);51virtual ~Wheel() = default;5253/// Get settings for the wheel54const WheelSettings * GetSettings() const { return mSettings; }5556/// Get the angular velocity (rad/s) for this wheel, note that positive means the wheel is rotating such that the car moves forward57float GetAngularVelocity() const { return mAngularVelocity; }5859/// Update the angular velocity (rad/s)60void SetAngularVelocity(float inVel) { mAngularVelocity = inVel; }6162/// Get the current rotation angle of the wheel in radians [0, 2 pi]63float GetRotationAngle() const { return mAngle; }6465/// Set the current rotation angle of the wheel in radians [0, 2 pi]66void SetRotationAngle(float inAngle) { mAngle = inAngle; }6768/// Get the current steer angle of the wheel in radians [-pi, pi], positive is to the left69float GetSteerAngle() const { return mSteerAngle; }7071/// Set the current steer angle of the wheel in radians [-pi, pi]72void SetSteerAngle(float inAngle) { mSteerAngle = inAngle; }7374/// Returns true if the wheel is touching an object75inline bool HasContact() const { return !mContactBodyID.IsInvalid(); }7677/// Returns the body ID of the body that this wheel is touching78BodyID GetContactBodyID() const { return mContactBodyID; }7980/// Returns the sub shape ID where we're contacting the body81SubShapeID GetContactSubShapeID() const { return mContactSubShapeID; }8283/// Returns the current contact position in world space (note by the time you call this the vehicle has moved)84RVec3 GetContactPosition() const { JPH_ASSERT(HasContact()); return mContactPosition; }8586/// Velocity of the contact point (m / s, not relative to the wheel but in world space)87Vec3 GetContactPointVelocity() const { JPH_ASSERT(HasContact()); return mContactPointVelocity; }8889/// Returns the current contact normal in world space (note by the time you call this the vehicle has moved)90Vec3 GetContactNormal() const { JPH_ASSERT(HasContact()); return mContactNormal; }9192/// Returns longitudinal direction (direction along the wheel relative to floor) in world space (note by the time you call this the vehicle has moved)93Vec3 GetContactLongitudinal() const { JPH_ASSERT(HasContact()); return mContactLongitudinal; }9495/// Returns lateral direction (sideways direction) in world space (note by the time you call this the vehicle has moved)96Vec3 GetContactLateral() const { JPH_ASSERT(HasContact()); return mContactLateral; }9798/// Get the length of the suspension for a wheel (m) relative to the suspension attachment point (hard point)99float GetSuspensionLength() const { return mSuspensionLength; }100101/// Check if the suspension hit its upper limit102bool HasHitHardPoint() const { return mSuspensionMaxUpPart.IsActive(); }103104/// Get the total impulse (N s) that was applied by the suspension105float GetSuspensionLambda() const { return mSuspensionPart.GetTotalLambda() + mSuspensionMaxUpPart.GetTotalLambda(); }106107/// Get total impulse (N s) applied along the forward direction of the wheel108float GetLongitudinalLambda() const { return mLongitudinalPart.GetTotalLambda(); }109110/// Get total impulse (N s) applied along the sideways direction of the wheel111float GetLateralLambda() const { return mLateralPart.GetTotalLambda(); }112113/// Internal function that should only be called by the controller. Used to apply impulses in the forward direction of the vehicle.114bool SolveLongitudinalConstraintPart(const VehicleConstraint &inConstraint, float inMinImpulse, float inMaxImpulse);115116/// Internal function that should only be called by the controller. Used to apply impulses in the sideways direction of the vehicle.117bool SolveLateralConstraintPart(const VehicleConstraint &inConstraint, float inMinImpulse, float inMaxImpulse);118119protected:120friend class VehicleConstraint;121122RefConst<WheelSettings> mSettings; ///< Configuration settings for this wheel123BodyID mContactBodyID; ///< ID of body for ground124SubShapeID mContactSubShapeID; ///< Sub shape ID for ground125Body * mContactBody = nullptr; ///< Body for ground126float mSuspensionLength; ///< Current length of the suspension127RVec3 mContactPosition; ///< Position of the contact point between wheel and ground128Vec3 mContactPointVelocity; ///< Velocity of the contact point (m / s, not relative to the wheel but in world space)129Vec3 mContactNormal; ///< Normal of the contact point between wheel and ground130Vec3 mContactLongitudinal; ///< Vector perpendicular to normal in the forward direction131Vec3 mContactLateral; ///< Vector perpendicular to normal and longitudinal direction in the right direction132Real mAxlePlaneConstant; ///< Constant for the contact plane of the axle, defined as ContactNormal . (WorldSpaceSuspensionPoint + SuspensionLength * WorldSpaceSuspensionDirection)133float mAntiRollBarImpulse = 0.0f; ///< Amount of impulse applied to the suspension from the anti-rollbars134135float mSteerAngle = 0.0f; ///< Rotation around the suspension direction, positive is to the left136float mAngularVelocity = 0.0f; ///< Rotation speed of wheel, positive when the wheels cause the vehicle to move forwards (rad/s)137float mAngle = 0.0f; ///< Current rotation of the wheel (rad, [0, 2 pi])138139AxisConstraintPart mSuspensionPart; ///< Controls movement up/down along the contact normal140AxisConstraintPart mSuspensionMaxUpPart; ///< Adds a hard limit when reaching the minimal suspension length141AxisConstraintPart mLongitudinalPart; ///< Controls movement forward/backward142AxisConstraintPart mLateralPart; ///< Controls movement sideways (slip)143};144145using Wheels = Array<Wheel *>;146147JPH_NAMESPACE_END148149150