GPU physics bridge — updated for engine16 / gpuPhysicsBridge Read GPU_SCENERY.txt for capsules, terrain/static mesh collision and event queues. Ordinary CS objects can now exchange impulses with a deformable GPU mesh. Their existing physics.cs/shared memory, mass, constraints and interpolation stay intact. GPU particles can collide with analytic obstacles or registered CS spheres/boxes. All contact forces are handled internally. Do not reposition bodies in a JS timer. Use standard load for CS objects; wait until the object exists before registering. Elastic sheet and CS ball load("sphere", "ball", 0, 5, 0) await createGPUMesh("sheet", "grid", {origin:{x:0,y:3,z:0},size:{x:6,y:1,z:6},resolution:12}) await enableGPUMeshPhysics("sheet", {mass:0.25,stiffness:100,damping:2,foundation:5}) await addGPUCollider("sheet", "ball") Freeze during setup if needed, then unfreeze once after registration. Never turn on Rigidbody interpolation: use the stock CS prefab setting (None). Mesh model A linear elastic reference network with nodal mass (kg), neighbor stiffness and rest-position foundation (N/m), damping (1/s), gravity (m/s²), friction, bounce and contact thickness (m). Open boundary vertices are pinned by default. This is a small-deformation model, not a general large-rotation/finite-element solid. Triangles keep their topology. Winding defines the supported side; a generated grid faces upwards. Sphere contact uses radius; box contact uses eight corners. showGPUPhysicsEnergy(name, maximum) displays nodal elastic energy in joules and mesh lines. It is NOT stress in pascals. Free nodes receive barycentric impulse weights; anchored nodes exchange momentum with their external support. Live controls setGPUPhysics(name, {stiffness:150,damping:3,bounce:0.2,friction:0.4}) pauseGPUPhysics(name) startGPUPhysics(name) resetGPUPhysics(name) Reset restores the GPU rest state and velocities, not participant CS positions. Reset a CS object's position/velocity once using ordinary CS commands. To change mass or boundary pinning, remove/recreate the GPU program. Solver-owned buffers cannot also be written/run by a user compute program. Surface display/query tools still work. Removing the program/clearRun releases solver buffers and registrations. GPU particles CreateGPUProgram with initial xyz f32 buffers named positions and velocities. enableGPUParticlePhysics(name, radius, {mass:0.01,gravity:{x:0,y:-9.81,z:0},bounce:0.5,damping:0}) addGPUObstacle(name, "floor", "plane", {position:{x:0,y:0,z:0},normal:{x:0,y:1,z:0}}) addGPUObstacle(name, "block", "box", {position:{x:0,y:1,z:0},size:{x:2,y:1,z:2}}) addGPUObstacle(name, "round", "sphere", {position:{x:0,y:1,z:0},radius:1}) addGPUCollider(name, "ball") removeGPUCollider(name, "floor") No Rigidbody per particle. Native GPU integration, gravity, drag, friction, restitution and analytic collision. Substep segment sweeps prevent crossing thin boxes/spheres; expanded box sweeps are conservative near rounded corners. Particle self-collision and deformable mesh interaction are optional in v18: setGPUParticleContacts and attachGPUDeformable. Read GPU_PARTICLE_CONTACTS.txt. Dynamic CS bodies receive summed impulse and torque; kinematic/static obstacles are externally driven boundaries. For dynamic particle coupling total particle mass must be <= one quarter of each dynamic body's mass. Inspect contacts var reply = await getGPUContacts("sheet") var contact = reply.contacts[0] contact.other, contact.collider, contact.phase contact.point, contact.normal, contact.impulse contact.triangle, contact.barycentric, contact.separation, contact.age Mesh records include triangle and barycentric coordinates on the CURRENT shape. Impulse is the impulse applied to the CS body (equal opposite goes into GPU nodes). Particle records aggregate contacts per obstacle, have triangle=-1, and do not provide a single surface normal. Inspect on demand for UI/scoring; never implement force exchange by polling these records in JS. Existing collisionWatch remains unchanged and does not report GPU contacts. Contact records are a latest batch, not a guaranteed event log; short enter/exit events can pass between reads. All GPU coordinates are Unity world coordinates. Legacy CS object's pos.x has opposite X convention; use consistent conversion when mixing the two APIs. Limits and diagnostics getGPUPhysicsState(name) returns physics and physicsSettings. physics reports running, pending, steps, simulatedTime, generation, bodies, samples, contacts, latency (seconds), dropped, readbackBytes, error. 16 collider shapes; 64 samples (sphere=1, box=8); mesh4096 vertices/8192 triangles; particle8192; substeps4..32; shared typed-program memory budget128MiB. Default8. Invalid settings/unsupported colliders produce explicit errors. Capsules are supported in v16; static MeshCollider/TerrainCollider use addGPUSceneCollider for particles. Sheared sphere/box/capsule transforms are rejected. Imported mesh source collisions are ignored only against registered participants, then the previous pair state is restored on removal. Do not add a second proxy that resolves the same contact in PhysX and the GPU bridge. GPU geometry stays on GPU. Only bounded contact/reaction summaries cross to CPU (up to6144 bytes/query). PhysX bodies necessarily run on CPU. Readback is async; results older than250ms are discarded. This is a bounded educational solver, not unrestricted rigidbody/mesh collision. Do not promise exact CCD on moving or folded deformable meshes or full arbitrary mesh-mesh collision. Examples: catalog/examples/gpu-physics-*.js; one saved manual activity per feature. Refresh the Game iframe after deployment; Run alone does not reload engine code.