Raytraced Audio is designed to run in parallel with your application. Once a raytracing context has been [[Creating a Raytracing Context|created and set up]], the update loop is:
- add / remove / update primitives - e.g. a player building a house, a door opening, etc.
- add / remove / update voices - e.g. update a voice to follow the player around
- update the raytracing context
A simple example of this is:
```cs
RaytracingContext context;
SpherePrimitive sphere;
Voice voice;
void Update()
{
// Update primitives
sphere.center = new Vector3F(5, 10 + globalTime, 20);
// Update voices
voice.position = new StaticPosition(4, 10 + globalTime, 4);
context.Update();
}
```
When `context.Update` is invoked:
- If the background raytracing threads are still running, do nothing
- Else:
- Process the results produced by the background threads:
- update reverb EAX
- update voice filters based on occlusion+permeation results
- update performance stats
- Apply any updated raytracing settings (see [[Updating Raytracing Settings]])
- Collate all new, changed or removed primitives for BVH recalculation
- Prepare voices for raytracing. New voices may be prioritised here for reduced playback latency (see [[Creating a Raytracing Context#prioritiseNewVoices]])
- Background raytracing threads are invoked (see [[Threading Architecture]])
As stated above, this is all designed to run in parallel to your application:
- You can invoke `context.Update` as many times as you like
- You can add/remove/modify any primitive/voice/listener at any time
- You can change any raytracing setting at any time
The only limitation is that all `context` data/functions/etc must only be used by one thread, i.e. your main thread.