Nvidia PhysX 学习文档4:The PhysX API

 


official site: https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/API.html#the-physx-api

红色代表需要弄懂的。


Introduction

This chapter covers the basic patterns common to the PhysX application programming interface (API.) We are committed to keeping this API stable and backwards-compatible from one minor release to the next, to protect the investment you make in your integration code.

该章节讲解API的基本用法。 API的各个版本是向后兼容的。

The PhysX API is composed primarily of abstract interface classes.  Classes, enumerations and functions defined by the API have the prefix Px.

physx api主要由抽象接口类构成。 API定义的 类,枚举,函数都使用Px前缀。

Note

There is currently one section of the public API which does not have the Px prefix: the PhysX Visual Debugger connection library which has the prefix Pvd.

API特例: PVD connection library的前缀是Pvd。

The PhysX libraries also expose some classes and functions that are not part of the public API. These are primarily containers and platform abstractions that are required to build the PhysX libraries which are distributed as source, and are also used in the samples.  They can be recognized because they do not have the Px prefix. Even though they are in principle accessible to users, they are largely undocumented and we do not maintain compatibility of this code between PhysX versions. For that reason we recommend strongly against their use in applications.

Physx libraries亦暴露了一些并不属于public api的类和函数, 这些东东的前置不是Px,没有详细文档,而且可能在不同的physx版本之间是相互不兼容的。 因此,强烈不建议用户使用。

Memory Management

PhysX performs all allocations via the PxAllocatorCallback interface. You must implement this interface in order to initialize PhysX:

所有的内存申请都通过class PxAllocatorCallback 。该类是个纯虚类,用户必须继承实现该类, 以初始化physx.

class PxAllocatorCallback
{
public:
    virtual ~PxAllocatorCallback() {}
    virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) = 0;
    virtual void deallocate(void* ptr) = 0;
};

The size of the request is specified in bytes, and PhysX requires that the memory that is returned be 16-byte aligned. On many platforms malloc() returns memory that is 16-byte aligned, and on Windows the system function _aligned_malloc() provides this capability. The other parameters to allocate() are a string which identifies the type of allocation, and the __FILE__ and __LINE__ location inside PhysX code where the allocation was made. Refer to PxAllocatorCallback::allocate() to find out more about them.

对于allocate函数的入参,size代表要求的字节数, physx要求分配的空间是16 bytes对齐的,即空间大小是16的倍数。 现在,在很多平台上,malloc()函数返回的memory大小是16字节对齐的,在windows系统上,其系统函数 _aligned_malloc()具备该功能。 入参 typeName表示type of allocation, 生于的两个入参代表 __FILE__ and __LINE__ location inside PhysX code where the allocation was made. 关于入参的更多信息见PxAllocatorCallback::allocate() 文档。

A simple implementation of the allocator callback class can be found in the PhysX Extensions library, see class PxDefaultAllocatorCallback.

官方提供了一个自带的对该类的实现:PxDefaultAllocatorCallback,在PhysX Extensions library里面。

Note

On some platforms PhysX uses system library calls to determine the correct type name, and the system function that returns the type name may call the system memory allocator. If you are instrumenting system memory allocations, you may observe this behavior. To prevent PhysX requesting type names, disable allocation names using the method PxFoundation::setReportAllocationNames().

在一些平台上,physx使用system library calls来确定正确的typeName, 使用的这个system function可能调用系统自身的memory allocator. To prevent PhysX requesting type names, disable allocation names using the method PxFoundation::setReportAllocationNames().

You can place PhysX objects in memory owned by the application using PhysX' binary deserialization mechanism. See Serialization for details.

用户可以将physx的objects放到应用程序的内存空间中,该功能对应Physx的' binary deserialization mechanism。 具体见Serialization

 

As an alternative to instrumenting the allocator, you can obtain detailed information about memory allocation in the PhysX Visual Debugger (see: PhysX Visual Debugger (PVD))

用户可以使用pvd来观察详细的内存分配信息。

Error Reporting

PhysX logs all error messages through the PxErrorCallback interface. You must implement this interface in order to initialize PhysX:

记录出错信息需要通过class PxErrorCallback, 纯虚类,用户必须实现它以初始化physx.

class UserErrorCallback : public PxErrorCallback
{
public:
    virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line)
    {
        // error processing implementation
        ...
    }
};

There is only a single function to implement, reportError. This function should log the passed message, or print it on the application's output console. For the more serious error codes eABORT, eINVALID_PARAMETER, eINVALID_OPERATION, eINTERNAL_ERROR and eOUT_OF_MEMORY, breaking into the debugger may be a more appropriate choice. Whatever you do, do not just ignore the messages.

用户只需要实现一个函数 reportErrot, 该函数应该记录外界传来的message或者将其打印到console。 第一个入是错误类比, 对于eABORT, eINVALID_PARAMETER, eINVALID_OPERATION, eINTERNAL_ERROR and eOUT_OF_MEMORY,这些比较严重的错误,breaking into the debugger may be a more appropriate choice。千万不要忽视错误。

A simple implementation of the error callback class can be found in the PhysX Extensions library, see class PxDefaultErrorCallback.

官方提供了一个实现即 class PxDefaultErrorCallback, 位于PhysX Extensions librar。

Math Classes

The common math classes used in PhysX are PxVec2, PxVec3, PxVec4, PxMat33, PxMat44, PxTransform, PxPlane and PxQuat, which are are defined in their respective header files, e.g. (SDKRoot)/Include/foundation/PxVec3.h. The types support standard operator overloads and typical math operations. Zero and identity objects where appropriate can be constructed by passing the arguments PxZero and PxIdentity respectively.

常用的数学类:  PxVec2, PxVec3, PxVec4, PxMat33, PxMat44, PxTransform, PxPlane and PxQuat, which are are defined in their respective header files, e.g. (SDKRoot)/Include/foundation/PxVec3.h.  通过传递PxZero 和PxIdentity参数,可以构造出Zero和identity 对象。

Some points to note are:

  • PxTransform is a representation of a rigid body transform as a rotation quaternion and a position vector, and PhysX functions which take transforms all use this type.
  • PxPlane is a homogeneous plane equation: that is, the constructor PxPlane(n, d) represents the equation n.x + d = 0.

PxMat33 and PxMat44 matrices represent transformations with basis vectors in the columns (pre-multiply with matrix on the left hand side) and are stored in column-major order. This format is layout compatible with popular graphics APIs such as OpenGL and Direct3D. For example, to set the model transformation for a rigid body in OpenGL:

DirectX uses row-major storage for matrices by default (D3DMATRIX), but also stores basis vectors in rows (post-multiply on the right), so PxMat44 may be used in place of D3DXMATRIX types directly.

PxMat33 ,PxMat44 矩阵代表着变换,其中的列是基向量, 矩阵的存储方式是列优先顺序。该种格式与流行的图像api ,eg, opengl,direct3D相兼容。

For example, to set the model transformation for a rigid body in OpenGL:

// retrieve world space transform of rigid body
PxTransform t = rigidActor.getGlobalPose(); // 从physx的actor中得到全局坐标系下的位姿信息。

// convert to matrix form
PxMat44 m = PxMat44(t);//可以直接将PxTransform 转换为 4*4位姿矩阵哎!!!!!!!!!!。

// set to OpenGL
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// PxMat44::front() returns a pointer to the first matrix element
glMultMatrixf(m.front());

// draw model

glPopMatrix()

 

Connecting PhysX Objects with User Application Objects

Often an application needs to associate PhysX objects with application objects for application logic or rendering purposes. An easy way to connect a single user application object with a PhysX object is to use the userData member provided by the most important PhysX classes (PxActor::userData, PxShape::userData, PxMaterial::userData, ...). The userData member is a void* pointer which is reserved for application use. Each class only has one userData field, so to manage multiple associations another mechanism must be used.

有时,为了逻辑需要或者渲染需要,用户须 associate PhysX objects with application objects,一个简单的方法是userData成员,大部分的Physx类都提供了该成员(例如,PxActor::userData, PxShape::userData, PxMaterial::userData, ...)。该成员是一个void*指针,是为了applicatioin use而定义哒。每个类只有一个userData field,因此,如果需要magange multiple associations的话,另一个机制需要被使用。

Type Casting

PhysX API interface classes inherit from a top-level interface called PxBase, which provides mechanisms for type-safe down-casting between interface types. For example, to cast from a PxActor to a PxRigidDynamic, use the following idiom:

PxActor* actor = <...>
PxRigidDynamic* myActor = actor->is<PxRigidDynamic>();

const PxActor* actor = <...>
const PxRigidDynamic* myActor = actor->is<PxRigidDynamic>();

PhysX API interface classes的基类是PxBase, 该类提供了interface type之间进行  type-safe down-casting 的机制。例如,将PxActor转换成PxRigidDynamic可以使用如下方法:(基类转换成子类类型, 之前没有用过哎。可能用于这种情况:某函数的入参是一个基类指针,然后,在函数体内,将入参转换成子类的指针。

PxActor* actor = <...>

PxRigidDynamic* myActor = actor->is<PxRigidDynamic>();

 

const PxActor* actor = <...>

const PxRigidDynamic* myActor = actor->is<PxRigidDynamic>();

This pattern can be used to cast to intermediate types in the hierarchy such as PxRigidActor, but this is somewhat slower than casting to concrete types. In addition, PxBase provides the following capabilities:

  • getConcreteType() provides an integer value which corresponds to the concrete type of an object
  • getConcreteTypeName() provides a string name of the concrete type
  • isKindOf() provides string-based testing of inheritance

 

Reference Counting

Some PhysX objects are designed to be shared and referenced multiple times in a PhysX scene graph. For example, a PxConvexMesh may be referenced by multiple PxShape objects, each sharing the same geometry but associated with different actors. The specific types are PxTriangleMesh, PxHeightField, PxConvexMesh, PxMaterial, and PxShape. Each object of these types has a reference count. The rules for reference counting are as follows:

一些physx对象可以被shared或referenced多次,例如,一个PxConvexMesh可以被多个 PxShape objects使用。其他举例:PxTriangleMesh, PxHeightField, PxConvexMesh, PxMaterial, and PxShape. 这些类的对象都有引用计数,引用计数的规则如下:

  • when an object is created from PxPhysics, it has a reference count of 1.
  • when an object's reference count reaches 0, the object is destroyed.
  • when a new counted reference is created, the reference count is incremented. Counted references are as follows:
    • when a PxShape references a PxConvexMesh, PxHeightfield, or PxTriangleMesh.
    • when a PxShape references a PxMaterial.
    • when a PxRigidActor references a PxShape. ??
  • when a counted reference is destroyed, or the object's release() method is called, the reference count is decremented.
  • when an object is created through deserialization, its reference count is 1, plus the number of counted references that exist to the object.

 

The initial reference count of 1 ensures the object is not destroyed until the application allows it by calling release() - thereafter it will be destroyed when no remaining counted references to it exist.

创建一个object之后其计数为1,然后,如果用户调用了release函数后,当 没有其他东东使用该对象时,该对象就会被销毁。 也就是说,如果没有调用release函数,即使没有其他任何东东使用该对象了,该对象也不会被销毁。

For example, if you create a shape using PxPhysics::createShape() and attach it to an actor with PxRigidActor::attachShape(), it has a reference count of 2. If you then call the shape's release() method, it has a reference count of 1. When the actor is destroyed, or the shape is detached from the actor, the reference count is decremented, and since it is now 0, the shape is destroyed.

例如,你用PxPhysics::createShape()函数创建了一个shape,并将通过 PxRigidActor::attachShape()将其attach给一个actor,这时该shape对象的计数为2。然后,如果你调用该shape的release函数,其计数变成1,然后,当该actor被销毁 或 shape被detached时, shape的计数变为0,就被销毁。

The acquireReference() method increments the reference count of an object. For example, when a spatial query returns a reference to a mesh shape, and you want to pass that result to another thread for deferred processing, incrementing the reference count will ensure that even if the shape referencing the mesh is released, the mesh continues to exist.

acquireReference()函数会将对象的引用计数加1,例如, 你使用spatial query返回一个mesh shape的引用,并打算将该引用传递到另一个线程,你可以调用acquireReference来对应用计数加一,着可以保证 即使该shape被released, mesh依然存在。

Note

subtypes of PxGeometry do not have counted references to the meshes to which they point, e.g. when PxConvexMeshGeometry points to a PxConvexMesh. A counted reference exists only when the geometry is within a PxShape.

PxGeometry 类型对它们指向的mesh没有引用计数,例如,当PxConvexMeshGeometry points to a PxConvexMesh。 A counted reference exists only when the geometry is within a PxShape.

Note

shapes are often created using the utility method PxRigidActorExt::createExclusiveShape(). Take special care when deserializing such actors (see Shapes and Reference Counting of Deserialized Objects)

通常使用PxRigidActorExt::createExclusiveShape()函数来创建shape, Take special care when deserializing such actors (see Shapes and Reference Counting of Deserialized Objects)

 

Using Different Units

PhysX is designed to produce correct results regardless of the units of length or mass, so long as inputs use those units consistently. However, there are certain tolerances values whose defaults need to be adjusted depending on the units. In order to ensure that these tolerances default to reasonable values, adjust the values in PxTolerancesScale when creating the PxPhysics and PxCooking interfaces. Tolerances for objects are set at creation time, and may then be overridden by the application.

只要单位始终一致,physx即可产生正确结果。 Tolerances的含义?

You should set tolerances based on the typical size of objects in your simulation. For example, if you are working with objects of size approximately one meter, but in units of centimeters, you should set the scale as follows:

如果你仿真的物体的长度大约为1m,但使用的长度单位时cm,则,设置scale.length=100(这样的设置的话,physx的内部长度单位就相当于cm了么)

PxFoundation* foundation = ...;
PxTolerancesScale scale;
scale.length = 100;        // typical length of an object
scale.speed = 981;         // typical speed of an object, gravity*1s is a reasonable choice
PxPhysics *p = PxCreatePhysics(PX_PHYSICS_VERSION, *foundation, scale, ...);

This will result in the defaults for values like PxShape::contactDistance being scaled appropriately for your objects.

You can also set the typical object mass in PxTolerancesScale.

It is important to use the same PxTolerances value for initialization of PxCooking and PxPhysics, and also when creating PxSceneDesc objects.

需要使用同一个PxTolerances 初始化PxCooking ,PxPhysics,PxSceneDesc。

Assertions

PhysX uses the PX_DEBUG macro to enable or disable assertions. This macro is not set in the PhysXCore and PhysXCommon libraries, and so by default these libraries will not trigger assertions, however you may configure the libraries provided as source to enable them. When an assert is triggered, PhysX calls an assert handler. By default the assert handler will trigger a debug breakpoint. However, you may call the function PxSetAssertHandler() to customize the assert handler.

使用PX_DEBUG宏来使用或者禁止断言。当断言被触发时,会调用队以ing的assert handler.

Determinism

PhysX is deterministic in the sense it will produce identical simulation results from the same sequence of API calls applied from the point where a scene is originally created (and the same responses from simulation callbacks which modify data). Note that removing all the objects from a scene is not in general sufficient to reinitialize it for this purpose.

从scene创建开始,同样的api调用会产生相同的仿真结果。 但是,仅仅从scene中移除所有的objects,然后运行同样的api可能产生不同的结果,即,必须重新create scene.

PhysX simulation behavior is not sensitive to the number of CPU worker threads used.

仿真行为 对 cpu的工作线程数目不敏感。

An important caveat to determinism is the state of the x87 FPU on 32-bit Intel/AMD platforms. Some compilers produce x87 floating point instructions even when configured to prefer SSE instructions, and the results of those operations may depend on the state of the x87 control word. Since it is too expensive to modify the x87 FPU state at every PhysX entry point, this is delegated to the application if necessary. PhysX operations do not result in changes to the x87 control word, but certain other libraries (including DirectX) may modify it.

Configurations in which this is known to be a issue are all 32-bit MSVC debug configurations, and all MSVC 32-bit checked, release and profile configurations prior to Visual Studio 2012.

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值