From b3cc7d7dbc6f9f28d91acab77a65f976a3c996a9 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 28 Mar 2025 02:44:12 +0100 Subject: it draws stuff --- viewer/resources.ts | 133 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 46 deletions(-) (limited to 'viewer/resources.ts') diff --git a/viewer/resources.ts b/viewer/resources.ts index 0340e31..0e9162e 100644 --- a/viewer/resources.ts +++ b/viewer/resources.ts @@ -44,63 +44,95 @@ function get_aabb(b: Uint8Array): AABB { } } +const object_cache = new Map() +async function ob_cached(r: Resource, make: () => Promise): Promise { + const k = r.toString() + const l = object_cache.get(k) + if (l) return l + const m = await make() + object_cache.set(k, m) + return m +} + export async function get_respackentry(r: Resource): Promise { - console.log(`load respackentry ${r}`); - const buf = await r.download_raw(); - const o: RespackEntry = {} - read_res_table(buf, (key, value) => { - switch (key) { - case "c_spatial_index": - o.c_spatial_index = new Resource(value) - break - default: - } - }); - return o + return await ob_cached(r, async () => { + const buf = await r.download_raw(); + const o: RespackEntry = {} + read_res_table(buf, (key, value) => { + switch (key) { + case "c_spatial_index": + o.c_spatial_index = new Resource(value) + break + default: + } + }); + return o + }) } export async function get_spatialindex(r: Resource): Promise { - // console.log(`load spatialindex ${r}`); - const buf = await r.download_raw(); - const o: SpatialIndex = { child: [] } - read_res_table(buf, (key, value) => { - switch (key) { - case "prefab": - o.prefab = new Resource(value) - break - case "child": - o.child.push([ - get_aabb(value.slice(0, 24)), - new Resource(value.slice(24, 56)) - ]) - break - default: - } - }); - return o + return await ob_cached(r, async () => { + const buf = await r.download_raw(); + const o: SpatialIndex = { child: [] } + read_res_table(buf, (key, value) => { + switch (key) { + case "prefab": + o.prefab = new Resource(value) + break + case "child": + o.child.push([ + get_aabb(value.slice(0, 24)), + new Resource(value.slice(24, 56)) + ]) + break + default: + } + }); + return o + }) } export async function get_prefab(r: Resource): Promise { - console.log(`load prefab ${r}`); - const buf = await r.download_raw(); - const o: Prefab = { graphics: [] } - read_res_table(buf, (key, value) => { - switch (key) { - case "graphics": - o.graphics.push([undefined as unknown as Affine3, new Resource(value.slice(48, 80))]) - break - default: - } - }); - return o + return await ob_cached(r, async () => { + const buf = await r.download_raw(); + const o: Prefab = { graphics: [] } + read_res_table(buf, (key, value) => { + let v, x = 0 + switch (key) { + case "graphics": + o.graphics.push([undefined as unknown as Affine3, new Resource(value.slice(48, 80))]) + break + case "transform": + v = new DataView(value.buffer.slice(0, 96)) + o.transform = [ + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + v.getFloat64((x++) * 8, true), + ] + break + default: + } + }); + return o + }) } export async function get_graphics_part(r: Resource): Promise { - console.log(`load graphics ${r}`); - return new GraphicsPart(await r.download_raw()) + return await ob_cached(r, async () => { + return new GraphicsPart(await r.download_raw()) + }) } export interface Vec3 { x: number, y: number, z: number } export interface AABB { min: Vec3, max: Vec3 } export interface Mat3 { x: Vec3, y: Vec3, z: Vec3 } -export interface Affine3 { basis: Mat3, origin: Vec3 } +export type Affine3 = [number, number, number, number, number, number, number, number, number, number, number, number] export interface SpatialIndex { level?: number @@ -111,8 +143,10 @@ export interface RespackEntry { c_spatial_index?: Resource } export interface Prefab { + transform?: Affine3, graphics: [Affine3, Resource][] } + export class GraphicsPart { commands: GraphicsCommand[] | undefined constructor(public buffer: Uint8Array) { } @@ -134,8 +168,14 @@ export class GraphicsPart { if (step == 0) out.push({ no_stroke: true }) else if (step == 1) out.push({ stroke: this.buffer[p + 0] }) else throw new Error("ccc"); + } else if (kind == 2) { + if (step == 4) out.push({ stroke_width: new DataView(this.buffer.buffer.slice(p, p + 4)).getFloat32(0) }) + else throw new Error("ddd"); + } else if (kind == 6) { + if (step == 12) out.push({ point: get_vec3(this.buffer.slice(p, p + 12)) }) + else throw new Error("eee"); } - else throw new Error("aaa"); + else throw new Error(`unknown gcmd ${kind}`); p += step } @@ -150,5 +190,6 @@ export interface GraphicsCommand { fill?: number, no_stroke?: true stroke?: number + stroke_width?: number point?: Vec3 } \ No newline at end of file -- cgit v1.2.3-70-g09d2