Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18,930 changes: 7,556 additions & 11,374 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/app/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const Config = {
MaxConcurrentTiles: 150,
MaxTilesPerWorker: 1,
WorkersCount: Math.min(4, navigator.hardwareConcurrency),
StartPosition: {lat: 40.76494, lon: -73.97860, pitch: 45, yaw: 0, distance: 2000},
StartPosition: {lat: 37.8199, lon: -122.4783, pitch: 45, yaw: 0, distance: 2000}, // Golden Gate Bridge (Strata)
MinCameraDistance: 10,
MaxCameraDistance: 4000,
SlippyMapTransitionDuration: 400,
Expand Down
797 changes: 797 additions & 0 deletions src/app/controls/DriveControlsNavigator.ts

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions src/app/objects/Car.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import RenderableObject3D from "./RenderableObject3D";
import AbstractMesh from "~/lib/renderer/abstract-renderer/AbstractMesh";
import AbstractRenderer from "~/lib/renderer/abstract-renderer/AbstractRenderer";
import {RendererTypes} from "~/lib/renderer/RendererTypes";
import {CarModelBuffers, createCarBody, createCarWheel, createCarPartsFromGLB, GLBWheelPart} from "~/app/objects/models/CarModel";
import Vec3 from "~/lib/math/Vec3";

// Strata Phase 2 Increment 4 — THROWAWAY GLUE. The car split into separately-drawable parts:
// one body mesh + one reusable wheel mesh (placed/animated 4x by GBufferPass.renderCar with its
// own part matrix for spin / steer / suspension). Both meshes are built lazily by the scene's
// getObjectsToUpdateMesh() traversal, like every other RenderableObject3D.
export default class Car extends RenderableObject3D {
// Strata Increment 4 Step B — throwaway A/B toggle (KeyB): when true, render the dropped GLB as a
// single static body mesh instead of the procedural box + animated wheels. Default false (box).
public static useGLB: boolean = false;

public bodyMesh: AbstractMesh = null;
public wheelMesh: AbstractMesh = null;

// GLB parts (Step B): a body mesh + 4 axle-centered wheel meshes with their mount metadata.
public glbBodyMesh: AbstractMesh = null;
public glbWheelMeshes: AbstractMesh[] = [];
public glbWheels: GLBWheelPart[] = [];
public glbWheelRadius: number = 0.34;
public glbReady: boolean = false;

private readonly bodyBuffers: CarModelBuffers = createCarBody();
private readonly wheelBuffers: CarModelBuffers = createCarWheel();

public constructor() {
super();

const box = this.bodyBuffers.boundingBox;
this.setBoundingBox(
new Vec3(box.min.x, box.min.y, box.min.z),
new Vec3(box.max.x, box.max.y, box.max.z)
);
}

public isMeshReady(): boolean {
return this.bodyMesh !== null && this.wheelMesh !== null;
}

private buildMesh(renderer: AbstractRenderer, buffers: CarModelBuffers): AbstractMesh {
return renderer.createMesh({
indexed: true,
indices: buffers.indices,
attributes: [
renderer.createAttribute({
name: 'position',
size: 3,
type: RendererTypes.AttributeType.Float32,
format: RendererTypes.AttributeFormat.Float,
normalized: false,
buffer: renderer.createAttributeBuffer({data: buffers.position})
}),
renderer.createAttribute({
name: 'normal',
size: 3,
type: RendererTypes.AttributeType.Float32,
format: RendererTypes.AttributeFormat.Float,
normalized: false,
buffer: renderer.createAttributeBuffer({data: buffers.normal})
}),
renderer.createAttribute({
name: 'color',
size: 3,
type: RendererTypes.AttributeType.UnsignedByte,
format: RendererTypes.AttributeFormat.Float,
normalized: true,
buffer: renderer.createAttributeBuffer({data: buffers.color})
})
]
});
}

public updateMesh(renderer: AbstractRenderer): void {
if (!this.bodyMesh) {
this.bodyMesh = this.buildMesh(renderer, this.bodyBuffers);
}

if (!this.wheelMesh) {
this.wheelMesh = this.buildMesh(renderer, this.wheelBuffers);
}

// Build the GLB parts once (best-effort; on failure the procedural box path keeps working).
if (!this.glbReady) {
try {
const parts = createCarPartsFromGLB();
this.glbBodyMesh = this.buildMesh(renderer, parts.body);
this.glbWheels = parts.wheels;
this.glbWheelRadius = parts.wheelRadius;
this.glbWheelMeshes = parts.wheels.map(w => w ? this.buildMesh(renderer, w.buffers) : null);
this.glbReady = true;
} catch (e) {
console.warn('[Strata] createCarPartsFromGLB failed, staying on procedural box:', e);
}
}
}
}
Loading