```cs
using vaudio;
public class Demo
{
RaytracingContext context;
PrismPrimitive prism;
Emitter listener;
Emitter enemy;
public Demo()
{
context = new RaytracingContext()
{
WorldSize = new Vector3F(100),
RenderingEnabled = true,
};
// Create a rectangular prism
prism = new PrismPrimitive()
{
// Set its material
material = MaterialType.Metal,
// Set its size
size = new Vector3F(20, 10, 20),
};
context.AddPrimitive(prism);
// Create a listener emitter
listener = new Emitter()
{
Name = "Listener",
ReverbRayCount = 1024,
ReverbBounceCount = 8,
OcclusionRayCount = 512,
OcclusionBounceCount = 8,
PermeationRayCount = 256,
PermeationBounceCount = 4,
AmbientPermeationRayCount = 128,
AmbientPermeationBounceCount = 4,
AffectsGroupedEAX = false,
ClampPosition = true,
};
context.AddEmitter(listener);
// Create an enemy emitter
enemy = new Emitter()
{
Name = "Enemy",
ReverbRayCount = 32,
ReverbBounceCount = 8,
AffectsGroupedEAX = true,
ClampPosition = false,
};
enemy.OnRaytracedByAnotherEmitter = (Emitter other) =>
{
var filter = other.GetFilter(enemy);
// PSEUDOCODE
Godot.PlaySound(SoundType.EnemySpawn, enemy.position, filter);
}
context.AddEmitter(enemy);
// Make the listener discover the enemy
listener.AddTarget(enemy);
}
Stopwatch watch = Stopwatch.StartNew();
public void Update()
{
// Rotate and position the prism in real time
var rotation = watch.ElapsedMilliseconds / 1000.0f;
prism.transform = Matrix4F.CreateRotationX(rotation) *
Matrix4F.CreateTranslation(30, 30, 30);
// Set the listener to the camera position
listener.Position = cameraPosition;
// Perform raytracing on background threads
context.Update();
}
}
```