diff options
author | metamuffin <metamuffin@disroot.org> | 2025-03-28 01:56:21 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-03-28 01:56:21 +0100 |
commit | 3be73a3c424bd7f72e6efecd6d954fbb08e960e0 (patch) | |
tree | dc8ed8557d352845ce4f892aa1f38b1df0cc638c /viewer/resources.ts | |
parent | 94837b601fb757ba6582602264b598df39f303fe (diff) | |
download | wearemapping-3be73a3c424bd7f72e6efecd6d954fbb08e960e0.tar wearemapping-3be73a3c424bd7f72e6efecd6d954fbb08e960e0.tar.bz2 wearemapping-3be73a3c424bd7f72e6efecd6d954fbb08e960e0.tar.zst |
a
Diffstat (limited to 'viewer/resources.ts')
-rw-r--r-- | viewer/resources.ts | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/viewer/resources.ts b/viewer/resources.ts new file mode 100644 index 0000000..0340e31 --- /dev/null +++ b/viewer/resources.ts @@ -0,0 +1,154 @@ + +export class Resource<T> { + constructor(public hash: Uint8Array) { } + toString() { + return Array.from(this.hash) + .map(e => e.toString(16).padStart(2, "0")) + .join("") + } + async download_raw() { + const res = await fetch(`http://127.0.0.1:28556/${this.toString()}`) + if (!res.ok) throw new Error("aaaa"); + return await res.bytes() + } +} + +export function read_res_table(buffer: Uint8Array, cb: (key: string, value: Uint8Array) => void) { + const view = new DataView(buffer.buffer) + let p = 0 + while (p < view.byteLength) { + const key_len = view.getInt16(p, true) + p += 2 + const value_len = view.getInt16(p, true) + p += 2 + const key = String.fromCharCode(...buffer.slice(p, p + key_len)) + p += key_len + const value = buffer.slice(p, p + value_len) + p += value_len + cb(key, value) + } +} + +function get_vec3(b: Uint8Array): Vec3 { + const k = new DataView(b.buffer) + return { + x: k.getFloat32(0, true), + y: k.getFloat32(4, true), + z: k.getFloat32(8, true), + } +} +function get_aabb(b: Uint8Array): AABB { + return { + min: get_vec3(b.slice(0, 12)), + max: get_vec3(b.slice(12, 24)) + } +} + +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 +} +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 +} +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 +} +export async function get_graphics_part(r: Resource<GraphicsPart>): Promise<GraphicsPart> { + console.log(`load graphics ${r}`); + 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 interface SpatialIndex { + level?: number + prefab?: Resource<undefined> + child: [AABB, Resource<undefined>][] +} +export interface RespackEntry { + c_spatial_index?: Resource<SpatialIndex> +} +export interface Prefab { + graphics: [Affine3, Resource<GraphicsPart>][] +} +export class GraphicsPart { + commands: GraphicsCommand[] | undefined + constructor(public buffer: Uint8Array) { } + + read(): GraphicsCommand[] { + if (this.commands) return this.commands + + const out: GraphicsCommand[] = [] + let p = 0 + while (p < this.buffer.length) { + const step = this.buffer[p + 0] + const kind = this.buffer[p + 1] + p += 2 + if (kind == 0) { + if (step == 0) out.push({ no_fill: true }) + else if (step == 1) out.push({ fill: this.buffer[p + 0] }) + else throw new Error("bbb"); + } else if (kind == 1) { + 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 throw new Error("aaa"); + + p += step + } + + this.commands = out + return out + } +} + +export interface GraphicsCommand { + no_fill?: true, + fill?: number, + no_stroke?: true + stroke?: number + point?: Vec3 +}
\ No newline at end of file |