Projekt_Grafika/dependencies/physx-4.1/include/PxArticulationReducedCoordi...

423 lines
15 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.
#ifndef PX_PHYSICS_NX_ARTICULATION_RC
#define PX_PHYSICS_NX_ARTICULATION_RC
/** \addtogroup physics
@{ */
#include "PxArticulationBase.h"
#include "foundation/PxVec3.h"
#include "foundation/PxTransform.h"
#include "solver/PxSolverDefs.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
PX_ALIGN_PREFIX(16)
struct PxSpatialForce
{
PxVec3 force;
PxReal pad0;
PxVec3 torque;
PxReal pad1;
}
PX_ALIGN_SUFFIX(16);
PX_ALIGN_PREFIX(16)
struct PxSpatialVelocity
{
PxVec3 linear;
PxReal pad0;
PxVec3 angular;
PxReal pad1;
}
PX_ALIGN_SUFFIX(16);
class PxJoint;
struct PxArticulationRootLinkData
{
PxTransform transform;
PxVec3 worldLinVel;
PxVec3 worldAngVel;
PxVec3 worldLinAccel;
PxVec3 worldAngAccel;
};
class PxArticulationCache
{
public:
enum Enum
{
eVELOCITY = (1 << 0), //!< The joint velocities this frame. Note, this is the accumulated joint velocities, not change in joint velocity.
eACCELERATION = (1 << 1), //!< The joint accelerations this frame. Delta velocity can be computed from acceleration * dt.
ePOSITION = (1 << 2), //!< The joint positions this frame. Note, this is the accumulated joint positions over frames, not change in joint position.
eFORCE = (1 << 3), //!< The joint forces this frame. Note, the application should provide these values for the forward dynamic. If the application is using inverse dynamic, this is the joint force returned.
eLINKVELOCITY = (1 << 4), //!< The link velocities this frame.
eLINKACCELERATION = (1 << 5), //!< The link accelerations this frame.
eROOT = (1 << 6), //!< Root link transform, velocity and acceleration. Note, when the application call applyCache with eROOT flag, it won't apply root link's acceleration to the simulation
eALL = (eVELOCITY | eACCELERATION | ePOSITION| eLINKVELOCITY | eLINKACCELERATION | eROOT )
};
PxArticulationCache() :
externalForces (NULL),
denseJacobian (NULL),
massMatrix (NULL),
jointVelocity (NULL),
jointAcceleration (NULL),
jointPosition (NULL),
jointForce (NULL),
rootLinkData (NULL),
coefficientMatrix (NULL),
lambda (NULL),
scratchMemory (NULL),
scratchAllocator (NULL),
version (0)
{}
PxSpatialForce* externalForces; // N = getNbLinks()
PxReal* denseJacobian; // N = 6*getDofs()*NumJoints, NumJoints = getNbLinks() - 1
PxReal* massMatrix; // N = getDofs()*getDofs()
PxReal* jointVelocity; // N = getDofs()
PxReal* jointAcceleration; // N = getDofs()
PxReal* jointPosition; // N = getDofs()
PxReal* jointForce; // N = getDofs()
PxSpatialVelocity* linkVelocity; // N = getNbLinks()
PxSpatialVelocity* linkAcceleration; // N = getNbLinks()
PxArticulationRootLinkData* rootLinkData; // root link Data
//application need to allocate those memory and assign them to the cache
PxReal* coefficientMatrix;
PxReal* lambda;
//These three members won't be set to zero when zeroCache get called
void* scratchMemory; //this is used for internal calculation
void* scratchAllocator;
PxU32 version; //cache version. If the articulation configuration change, the cache is invalid
};
typedef PxFlags<PxArticulationCache::Enum, PxU8> PxArticulationCacheFlags;
PX_FLAGS_OPERATORS(PxArticulationCache::Enum, PxU8)
/**
\brief a tree structure of bodies connected by joints that is treated as a unit by the dynamics solver
Articulations are more expensive to simulate than the equivalent collection of
PxRigidDynamic and PxJoint structures, but because the dynamics solver treats
each articulation as a single object, they are much less prone to separation and
have better support for actuation. An articulation may have at most 64 links.
@see PxArticulationJoint PxArticulationLink PxPhysics.createArticulation
*/
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxArticulationReducedCoordinate : public PxArticulationBase
{
public:
virtual void release() = 0;
/**
\brief Sets flags on the articulation
\param[in] flags Articulation flags
*/
virtual void setArticulationFlags(PxArticulationFlags flags) = 0;
/**
\brief Raises or clears a flag on the articulation
\param[in] flag The articulation flag
\param[in] value true/false indicating whether to raise or clear the flag
*/
virtual void setArticulationFlag(PxArticulationFlag::Enum flag, bool value) = 0;
/**
\brief return PxArticulationFlags
*/
virtual PxArticulationFlags getArticulationFlags() const = 0;
/**
\brief returns the total Dofs of the articulation
*/
virtual PxU32 getDofs() const = 0;
/**
\brief create an articulation cache
\note this call may only be made on articulations that are in a scene, and may not be made during simulation
*/
virtual PxArticulationCache* createCache() const = 0;
/**
\brief Get the size of the articulation cache
\note this call may only be made on articulations that are in a scene, and may not be made during simulation
*/
virtual PxU32 getCacheDataSize() const = 0;
/**
\brief zero all data in the articulation cache beside the cache version
\note this call may only be made on articulations that are in a scene, and may not be made during simulation
*/
virtual void zeroCache(PxArticulationCache& cache) = 0;
/**
\brief apply the user defined data in the cache to the articulation system
\param[in] cache articulation data.
\param[in] flag The mode to use when determine which value in the cache will be applied to the articulation
\param[in] autowake Specify if the call should wake up the articulation if it is currently asleep. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
@see createCache copyInternalStateToCache
*/
virtual void applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, bool autowake = true) = 0;
/**
\brief copy the internal data of the articulation to the cache
\param[in] cache articulation data
\param[in] flag this indicates what kind of data the articulation system need to copy to the cache
@see createCache applyCache
*/
virtual void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const = 0;
/**
\brief release an articulation cache
\param[in] cache the cache to release
@see createCache applyCache copyInternalStateToCache
*/
virtual void releaseCache(PxArticulationCache& cache) const = 0;
/**
\brief reduce the maximum data format to the reduced internal data
\param[in] maximum joint data format
\param[out] reduced joint data format
*/
virtual void packJointData(const PxReal* maximum, PxReal* reduced) const = 0;
/**
\brief turn the reduced internal data to maximum joint data format
\param[in] reduced joint data format
\param[out] maximum joint data format
*/
virtual void unpackJointData(const PxReal* reduced, PxReal* maximum) const = 0;
/**
\brief initialize all the common data for inverse dynamics
*/
virtual void commonInit() const = 0;
/**
\brief determine the statically balance of the joint force of gravity for entire articulation. External force, joint velocity and joint acceleration
are set to zero, the joint force returned will be purely determined by gravity.
\param[out] cache return joint forces which can counteract gravity force
@see commonInit
*/
virtual void computeGeneralizedGravityForce(PxArticulationCache& cache) const = 0;
/**
\brief determine coriolise and centrifugal force. External force, gravity and joint acceleration
are set to zero, the joint force return will be coriolise and centrifugal force for each joint.
\param[in] cache data
@see commonInit
*/
virtual void computeCoriolisAndCentrifugalForce(PxArticulationCache& cache) const = 0;
/**
\brief determine joint force change caused by external force. Gravity, joint acceleration and joint velocity
are all set to zero.
\param[in] cache data
@see commonInit
*/
virtual void computeGeneralizedExternalForce(PxArticulationCache& cache) const = 0;
/**
\brief determine the joint acceleration for each joint
This is purely calculates the change in joint acceleration due to change in the joint force
\param[in] cache articulation data
@see commonInit
*/
virtual void computeJointAcceleration(PxArticulationCache& cache) const = 0;
/**
\brief determine the joint force
This is purely calculates the change in joint force due to change in the joint acceleration
This means gravity and joint velocity will be zero
\param[in] cache return joint force
@see commonInit
*/
virtual void computeJointForce(PxArticulationCache& cache) const = 0;
/**
\brief compute the dense Jacobian for the entire articulation in world space
\param[out] cache sets cache.denseJacobian matrix. The matrix is indexed [nCols * row + column].
\param[out] nRows set to number of rows in matrix, which corresponds to the number of articulation links times 6.
\param[out] nCols set to number of columns in matrix, which corresponds to the number of joint DOFs, plus 6 in the case eFIX_BASE is false.
Note that this computes the dense representation of an inherently sparse matrix. Multiplication with this matrix maps
joint space velocities to 6DOF world space linear and angular velocities.
*/
virtual void computeDenseJacobian(PxArticulationCache& cache, PxU32& nRows, PxU32& nCols) const = 0;
/**
\brief compute the coefficient matrix for contact force.
\param[out] cache returns the coefficient matrix. Each column is the joint force effected by a contact based on impulse strength 1
@see commonInit
*/
virtual void computeCoefficientMatrix(PxArticulationCache& cache) const = 0;
/**
\brief compute the lambda value when the test impulse is 1
\param[in] initialState the initial state of the articulation system
\param[in] jointTorque M(q)*qddot + C(q,qdot) + g(q)
\param[in] maxIter maximum number of solver iterations to run. If the system converges, fewer iterations may be used.
\param[out] cache returns the coefficient matrix. Each column is the joint force effected by a contact based on impulse strength 1
@see commonInit
*/
virtual bool computeLambda(PxArticulationCache& cache, PxArticulationCache& initialState, const PxReal* const jointTorque, const PxU32 maxIter) const = 0;
/**
\brief compute the joint-space inertia matrix
\param[in] cache articulation data
@see commonInit
*/
virtual void computeGeneralizedMassMatrix(PxArticulationCache& cache) const = 0;
/**
\brief add loop joint to the articulation system for inverse dynamic
\param[in] joint required to add loop joint
@see commonInit
*/
virtual void addLoopJoint(PxJoint* joint) = 0;
/**
\brief remove loop joint from the articulation system
\param[in] joint required to remove loop joint
@see commonInit
*/
virtual void removeLoopJoint(PxJoint* joint) = 0;
/**
\brief returns the number of loop joints in the articulation
\return number of loop joints
*/
virtual PxU32 getNbLoopJoints() const = 0;
/**
\brief returns the set of loop constraints in the articulation
\param[in] userBuffer buffer into which to write an array of constraints pointers
\param[in] bufferSize the size of the buffer. If this is not large enough to contain all the pointers to links,
only as many as will fit are written.
\param[in] startIndex Index of first link pointer to be retrieved
\return the number of links written into the buffer.
@see ArticulationLink
*/
virtual PxU32 getLoopJoints(PxJoint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief returns the required size of coeffient matrix in the articulation. The coefficient matrix is number of constraint(loop joints) by total dofs. Constraint Torque = transpose(K) * lambda(). Lambda is a vector of number of constraints
\return bite size of the coefficient matrix(nc * n)
*/
virtual PxU32 getCoefficientMatrixSize() const = 0;
/**
\brief teleport root link to a new location
\param[in] pose the new location of the root link
\param[in] autowake wake up the articulation system
@see commonInit
*/
virtual void teleportRootLink(const PxTransform& pose, bool autowake) = 0;
/**
\brief return the link velocity in world space with the associated low-level link index(getLinkIndex()).
\param[in] linkId low-level link index
@see getLinkIndex() in PxArticulationLink
*/
virtual PxSpatialVelocity getLinkVelocity(const PxU32 linkId) = 0;
/**
\brief return the link acceleration in world space with the associated low-level link index(getLinkIndex())
\param[in] linkId low-level link index
@see getLinkIndex() in PxArticulationLink
*/
virtual PxSpatialVelocity getLinkAcceleration(const PxU32 linkId) = 0;
protected:
PX_INLINE PxArticulationReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationReducedCoordinate(PxBaseFlags baseFlags) : PxArticulationBase(baseFlags) {}
virtual ~PxArticulationReducedCoordinate() {}
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
/** @} */
#endif