How to save cooked geometry data in PhysX?

In PhysX 3.3.4, convexmesh\trianglemesh\heightfield should be cooked before use, and they could be cooked offline or at runtime.

According to http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Geometry.html, we can cook a geometry in two manners:

offline manner by streaming

PxDefaultMemoryOutputStream writeBuffer;
cooking.cookTriangleMesh(someDescription, writeBuffer);
PxDefaultMemoryInputData readBuffer(writeBuffer.getData(), writeBuffer.getSize());
PxTriangleMesh* aTriangleMesh = physics.createTriangleMesh(readBuffer);

runtime manner by cook api

PxTriangleMesh* aTriangleMesh = theCooking->createTriangleMesh(meshDesc, thePhysics->getPhysicsInsertionCallback());

According to this page, if I want the best performance at runtime, I should use the offline manner. I read the source code of PhysX and found them identical, except for an extra stream in offline manner containing data generated at cook time. So to speed up performance, should I save the stream to disk and recovery the cooked data at runtime to make cook actually “offline”?

However, http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Serialization.html says that


Note: cooking also generates a binary output stream. The primary purpose of cooking, however, is to translate from a user format to a format suitable for the SDK runtime, and so it is not considered a serialization mechanism. Loading a cooked mesh from a stream involves allocation and endian conversion. As a consequence, it is much less efficient than PhysX’ binary serialization mechanism. See http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/RigidBodyCollision.html#rigidbodycollisionshapes for more details about cooking.

So the stream generated in the offline cook manner should not be stored at disk. If that is the case, what does the redundancy stream for?

If I use the PhysX binary serialization mechanism, how to make the cook procedure offline and achieve the best performance?

PhysX offers 2 different approaches:

(1) A mechanism to cook geometries and save this format to a stream (e.g. disk, network etc.)
(2) A mechanism to serialise a collection of actors/shapes/constraints etc. to a stream.

Option (1) is how most engines would normally manage pre-cooked assets. In this case, you would cook and save a PxConvexMeshGeometry, PxTriangleMeshGeometry etc. in your offline tool and then load this cooked asset in your runtime application. You would include this data alongside other representations of this asset (e.g. the graphical representation) - possibly as different data blocks in the same asset file. However, as noted, this loading code performs allocations to allocate buffers for vertices, indices etc. at suitable sizes and, if the endianness of the serialized data differs from that of the platform it’s being loaded on, it will perform endian swaps. However, this approach is still perfectly usable and is the mechanism the majority of game engines will use. It will be significantly faster than cooking your actors at runtime. It also supports loading models cooked using legacy formats in newer versions of PhysX, which means you can potentially upgrade your game engine to use a newer version of PhysX but still function correctly with existing assets without needing to re-cook.

Option (2) is the full binary serialisation/deserialization mechanism. In this case, you serialise and de-serialise a PxCollection, which can contain a mixture of actors, shapes, constraints, materials etc. in a binary format that exactly matches the layout of those classes in the version of PhysX that it was serialised from. This collection of actors, shapes etc. can reference each other, e.g. an actor has multiple shapes, each of which make use of specific materials etc. This feature minimises allocations and effectively just reads the data straight from disk into a buffer, resolves any pointers and then your PxActors, PxShapes, PxConstraints etc. are ready to use. However, we don’t guarantee binary compatibility between releases so, using this approach would mean that a version upgrade would require all assets to be re-authored.

In general, for storing assets in your game, we’d recommend option (1) over option (2) because it’s a bit more flexible and usually fits nicely into authoring pipelines.

Hope this helps