feat: 3 scene rendering setup

This commit is contained in:
2026-03-18 08:49:51 -04:00
parent 933c6afd08
commit 358122a74a
33 changed files with 1094 additions and 1132 deletions

View File

@@ -5,17 +5,16 @@ import {
STAR_RENDER_SCALE,
} from "./viewerConstants";
import type {
CelestialSnapshot,
ClaimSnapshot,
ConstructionSiteSnapshot,
LocalBubbleSnapshot,
PlanetSnapshot,
ResourceNodeSnapshot,
ShipSnapshot,
SpatialNodeSnapshot,
StationSnapshot,
SystemSnapshot,
} from "./contracts";
import type { MoonVisual, SystemSummaryVisual } from "./viewerTypes";
import type { MoonVisual } from "./viewerTypes";
import {
celestialRenderRadius,
computeMoonOrbitRadius,
@@ -46,10 +45,10 @@ export function createNodeMesh(node: ResourceNodeSnapshot): SceneNode {
return createSceneNode(mesh);
}
export function createSpatialNodeMesh(node: SpatialNodeSnapshot, spatialNodeColor: (kind: string) => string): SceneNode {
const color = spatialNodeColor(node.kind);
export function createCelestialMesh(node: CelestialSnapshot, celestialColor: (kind: string) => string): SceneNode {
const color = celestialColor(node.kind);
return createSceneNode(new THREE.Mesh(
new THREE.OctahedronGeometry(10, 0),
new THREE.OctahedronGeometry(0.08, 0),
new THREE.MeshStandardMaterial({
color,
emissive: new THREE.Color(color).multiplyScalar(0.16),
@@ -59,23 +58,6 @@ export function createSpatialNodeMesh(node: SpatialNodeSnapshot, spatialNodeColo
));
}
export function createBubbleRing(
bubble: LocalBubbleSnapshot,
localPosition: THREE.Vector3,
createCirclePoints: (radius: number, segments: number) => THREE.Vector3[],
): SceneNode {
const ring = new THREE.LineLoop(
new THREE.BufferGeometry().setFromPoints(createCirclePoints(Math.max(bubble.radius, 60), 64)),
new THREE.LineBasicMaterial({
color: 0x6ed6ff,
transparent: true,
opacity: 0.32,
}),
);
ring.position.copy(localPosition);
return createSceneNode(ring);
}
export function createClaimMesh(claim: ClaimSnapshot): SceneNode {
return createSceneNode(new THREE.Mesh(
new THREE.ConeGeometry(9, 20, 4),
@@ -363,20 +345,34 @@ export function createTacticalIcon(documentRef: Document, color: string, size: n
return createSceneNode(sprite);
}
export function createSystemSummaryVisual(documentRef: Document, anchor: THREE.Vector3): SystemSummaryVisual {
export function createStarDot(documentRef: Document, color: string): SceneNode {
const canvas = documentRef.createElement("canvas");
canvas.width = 512;
canvas.height = 160;
canvas.width = 32;
canvas.height = 32;
const context = canvas.getContext("2d");
if (!context) {
throw new Error("Unable to create star dot canvas");
}
context.clearRect(0, 0, 32, 32);
context.fillStyle = color;
context.beginPath();
context.arc(16, 16, 12, 0, Math.PI * 2);
context.fill();
const texture = new THREE.CanvasTexture(canvas);
const sprite = createSceneNode(new THREE.Sprite(new THREE.SpriteMaterial({
const sprite = new THREE.Sprite(new THREE.SpriteMaterial({
map: texture,
transparent: true,
depthWrite: false,
depthTest: false,
})));
sprite.object.scale.set(520, 160, 1);
sprite.setVisible(false);
return { sprite, texture, anchor };
color: "#ffffff",
fog: false,
}));
sprite.scale.setScalar(4);
sprite.visible = false;
return createSceneNode(sprite);
}
export function createShellReticle(documentRef: Document, color: string, size: number): SceneNode {