Back to Supersonic RC Revive
SOURCE / PINNED RELEASE

Made of little things.

Supersonic RC Revive

Release
1ba42f1ca1d6…
Author-recorded commit
baecad10b1cd…
License
LICENSE
Author’s source reference
nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-143146b0d6f

Archive hash verified: 90d22b206672eba4…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/game/physics/rayWorld.ts
// modelsUnderRay(origin, direction, 1, #detailed) against the static copy of
// the level ("3d2" in the original), which the wheels and camera raycast into.
// Shockwave 3D only reports front faces (every level model has the default
// #front visibility): the original's logger shows an upside-down car's wheel
// rays, which start just under the floor, finding no ground. Testing back faces
// made them read full compression and fling the car.
import { BufferAttribute, BufferGeometry, FrontSide, Ray, Vector3 } from 'three';
import { MeshBVH } from 'three-mesh-bvh';

export interface RayHit {
  model: string;
  isectPosition: Vector3;
  isectNormal: Vector3;
  distance: number;
}

export class RayWorld {
  private readonly bvh: MeshBVH;
  private readonly owner: Uint16Array;
  private readonly ray = new Ray();

  constructor(
    positions: Float32Array,
    indices: Uint32Array,
    owner: Uint16Array,
    private readonly modelNames: string[],
  ) {
    const geometry = new BufferGeometry();
    geometry.setAttribute('position', new BufferAttribute(positions, 3));
    geometry.setIndex(new BufferAttribute(indices, 1));
    this.owner = owner;
    this.bvh = new MeshBVH(geometry);
  }

  /** First hit along the ray (direction need not be normalised), or null. */
  modelsUnderRay(origin: Vector3, direction: Vector3): RayHit | null {
    this.ray.origin.copy(origin);
    this.ray.direction.copy(direction).normalize();
    const hit = this.bvh.raycastFirst(this.ray, FrontSide);
    if (!hit || !hit.face || hit.faceIndex == null) return null;
    return {
      model: this.modelNames[this.owner[hit.faceIndex]] ?? '',
      isectPosition: hit.point.clone(),
      isectNormal: hit.face.normal.clone(),
      distance: hit.distance,
    };
  }
}