diff options
Diffstat (limited to 'viewer/resources.ts')
-rw-r--r-- | viewer/resources.ts | 133 |
1 files changed, 87 insertions, 46 deletions
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<T>(r: Resource<T>, make: () => Promise<T>): Promise<T> { + 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<RespackEntry>): Promise<RespackEntry> { - 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<SpatialIndex>): Promise<SpatialIndex> { - // 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<Prefab>): Promise<Prefab> { - 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<GraphicsPart>): Promise<GraphicsPart> { - 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<SpatialIndex> } export interface Prefab { + transform?: Affine3, graphics: [Affine3, Resource<GraphicsPart>][] } + 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 |