summaryrefslogtreecommitdiff
path: root/viewer
diff options
context:
space:
mode:
Diffstat (limited to 'viewer')
-rw-r--r--viewer/helper.ts2
-rw-r--r--viewer/main.ts26
-rw-r--r--viewer/resources.ts133
3 files changed, 107 insertions, 54 deletions
diff --git a/viewer/helper.ts b/viewer/helper.ts
index e8b675f..bc634a6 100644
--- a/viewer/helper.ts
+++ b/viewer/helper.ts
@@ -2,4 +2,4 @@ import { AABB } from "./resources.ts";
export function aabb_overlap(a: AABB, b: AABB): boolean {
return true
-} \ No newline at end of file
+}
diff --git a/viewer/main.ts b/viewer/main.ts
index e0c2fde..f59bb1c 100644
--- a/viewer/main.ts
+++ b/viewer/main.ts
@@ -18,12 +18,16 @@ function draw() {
ctx.fillStyle = "black"
ctx.fillRect(0, 0, canvas.width, canvas.height)
- loader?.root.children
+ loader?.root.draw()
requestAnimationFrame(draw)
}
-
-canvas.addEventListener("resize", () => draw())
+function resize() {
+ canvas.width = globalThis.innerWidth
+ canvas.height = globalThis.innerHeight
+}
+canvas.addEventListener("resize", () => resize())
+resize()
draw()
@@ -42,7 +46,7 @@ async function init() {
}
init()
-let limit = 100;
+let limit = 10000;
class Loader {
view: AABB
@@ -64,8 +68,10 @@ class SNode {
this.children = new Array(data.child.length).fill(undefined)
}
async load(view: AABB) {
- if (this.data.prefab && !this.prefab) this.prefab = await get_prefab(this.data.prefab)
- if (this.prefab?.graphics[0] && !this.graphics) this.graphics = await get_graphics_part(this.prefab.graphics[0][1])
+ if (this.data.prefab && !this.prefab)
+ this.prefab = await get_prefab(this.data.prefab)
+ if (this.prefab?.graphics[0] && !this.graphics)
+ this.graphics = await get_graphics_part(this.prefab.graphics[0][1])
for (let i = 0; i < this.data.child.length; i++) {
const [aabb, child_data_hash] = this.data.child[i];
if (!aabb_overlap(aabb, view)) continue
@@ -82,8 +88,14 @@ class SNode {
if (c) c.draw()
}
if (!this.graphics) return
+ ctx.fillStyle = "red"
+ ctx.save()
+ ctx.scale(100000, 100000)
+ ctx.translate(-0.155, -0.63)
+ ctx.translate(this.prefab!.transform![10], this.prefab!.transform![11])
for (const c of this.graphics.read()) {
- console.log(c);
+ if (c.point) ctx.fillRect(c.point.x, c.point.y, 0.00003, 0.00003)
}
+ ctx.restore()
}
}
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