.. APEX Particle Integration Guide

===============================
APEX Particle Integration Guide
===============================

Introduction
============

This document gives some tips and guidelines for how to integrate APEX
particles into a game that uses PhysX 3.x, to get the best performance
without sacrificing visual quality.

CUDA Context Manager
====================

- Do not share a single CudaContextManager between multiple scenes. Although
  the API does allow you to do this, if you share the CudaContextManager
  there will be dependencies created between scenes on CUDA work. Most of
  the time this is not what you want.
- Do not use a CudaContextManager on scenes that don't use GPU features. For
  example, if you have a primary scene for handling standard rigid body
  interactions in your game, and an effects scene for handling APEX
  particles, you would only need to give a CudaContextManager to the effects
  scene.


Second Effects Scene
====================

If your game already uses PhysX 3.x for gameplay-affecting rigid body
simulation, it may make sense to simulate APEX particles in a separate
scene so your game logic won't be blocked waiting for the APEX simulation
to complete. We recommend keeping your primary PxScene as-is, and creating a
second effects PxScene paired with an Scene for APEX particle effects.
The effects scene can be stepped whenever convenient. Any rigid bodies or
shapes you want to interact with APEX particles must be mirrored into the
effects scene.

.. figure:: images/apex_psys_second_scene.png
    :height: 424
    :width: 586
    :alt: Second effects scene

Stepping the effects scene
--------------------------

Even if you use multiple simulation steps per frame in your primary scene,
we recommend using a single variable-length timestep in the effects scene.
In other words, just pass the elapsed time to the effects scene's simulate()
once each frame. If necessary, you could set a minimum and maximum timestep
size.

The effects scene does not have to be stepped at the same time as the
primary scene. You could call effectsScene->simulate() earlier and
effectsScene->fetchResults() later than the primary scene to allow it to
simulate in parallel with other game work.

Mirroring shapes to the effects scene
-------------------------------------

Any rigid bodies or shapes you want to interact with APEX particles must be
mirrored into the effects scene from the primary scene. Keep in mind that
you should only add objects to the effects scene when the effects scene is
not being simulated. You may be able to get away with much simpler
primitives in your effects scene. For example, even if you have a very 
detailed collision model for your character controller (to detect head shots 
for example) you could probably just mirror it into the effects scene as a 
single capsule that approximates the size of the character.

You may want to mirror static geometry into the effects scene so that APEX
particles interact with the static environment. Static geometry typically
doesn't get updated once it's created so this could be done once as the
geometry is loaded. Dynamic rigid bodies should be mirrored into the effects 
scene as kinematics. The PhysX 3.x Extensions include PxCloneDynamic and 
PxCloneStatic helpers to get you started. See the PhysX documentation for 
more details.

Fully asynchronous effects scene
--------------------------------

If you want to be able to add APEX particle effects with minimal impact on
the game's frame rate, you can take it a step further and create a fully
asynchronous effects scene. In this model you step the effects scene in a
separate thread at whatever rate you can simulate it at. You buffer the
render data and in your game's normal render loop you render the most
recently completed APEX particle render data. If the effects scene
simulation time falls behind the game's frame time, you will see a visual
artifact of the particles stuttering, but without any large impact on
overall frame rate.

The benefit is the minimal impact the particle effects have on frame rate.
The downside is that it becomes more complex to manage the effects scene.
Here are some of the things you'll want to check that you're handling
properly:

- You will need to handle safe communication between your main game thread and
  the thread managing the effects scene.
- You will have to handle the case where a shape that gets mirrored is added
  to the primary scene, queued up to be added to the effects scene, then
  deleted from the primary before it has been added to the effects scene.
- You will have to mirror updates to the mirrored objects like pose or
  collision group changes.
- You will need to double-buffer the particle rendering data received from
  APEX in the effects thread and pass it safely to the rendering thread.
  You will most likely be calling simulate, fetchResults,
  dispatchRenderResources, and updateRenderResources all from the effects
  thread.
- There's no point in simulating the effects more than once a frame, so
  you'll also want to limit how often simulate gets called on the effects
  scene when simulation time is low.

