diff --git a/packages/frontend/assets/room/objects/banknote/banknote.blend b/packages/frontend/assets/room/objects/banknote/banknote.blend
new file mode 100644
index 0000000000..60b1968a29
Binary files /dev/null and b/packages/frontend/assets/room/objects/banknote/banknote.blend differ
diff --git a/packages/frontend/assets/room/objects/banknote/banknote.glb b/packages/frontend/assets/room/objects/banknote/banknote.glb
new file mode 100644
index 0000000000..f4ef0b91e7
Binary files /dev/null and b/packages/frontend/assets/room/objects/banknote/banknote.glb differ
diff --git a/packages/frontend/assets/room/objects/banknote/tex.png b/packages/frontend/assets/room/objects/banknote/tex.png
new file mode 100644
index 0000000000..9106dc1457
Binary files /dev/null and b/packages/frontend/assets/room/objects/banknote/tex.png differ
diff --git a/packages/frontend/assets/room/objects/bed/bed.blend b/packages/frontend/assets/room/objects/bed/bed.blend
new file mode 100644
index 0000000000..731df76d0c
Binary files /dev/null and b/packages/frontend/assets/room/objects/bed/bed.blend differ
diff --git a/packages/frontend/assets/room/objects/bed/bed.glb b/packages/frontend/assets/room/objects/bed/bed.glb
new file mode 100644
index 0000000000..f35ecb9ef4
Binary files /dev/null and b/packages/frontend/assets/room/objects/bed/bed.glb differ
diff --git a/packages/frontend/assets/room/objects/bin/bin.blend b/packages/frontend/assets/room/objects/bin/bin.blend
new file mode 100644
index 0000000000..8d459a0869
Binary files /dev/null and b/packages/frontend/assets/room/objects/bin/bin.blend differ
diff --git a/packages/frontend/assets/room/objects/bin/bin.glb b/packages/frontend/assets/room/objects/bin/bin.glb
new file mode 100644
index 0000000000..b45f203802
Binary files /dev/null and b/packages/frontend/assets/room/objects/bin/bin.glb differ
diff --git a/packages/frontend/assets/room/objects/book/book.blend b/packages/frontend/assets/room/objects/book/book.blend
new file mode 100644
index 0000000000..0d4899d4ae
Binary files /dev/null and b/packages/frontend/assets/room/objects/book/book.blend differ
diff --git a/packages/frontend/assets/room/objects/book/book.glb b/packages/frontend/assets/room/objects/book/book.glb
new file mode 100644
index 0000000000..546893da06
Binary files /dev/null and b/packages/frontend/assets/room/objects/book/book.glb differ
diff --git a/packages/frontend/assets/room/objects/book2/barcode.png b/packages/frontend/assets/room/objects/book2/barcode.png
new file mode 100644
index 0000000000..37cfe5add3
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/barcode.png differ
diff --git a/packages/frontend/assets/room/objects/book2/book2.blend b/packages/frontend/assets/room/objects/book2/book2.blend
new file mode 100644
index 0000000000..e0fdb48101
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/book2.blend differ
diff --git a/packages/frontend/assets/room/objects/book2/book2.glb b/packages/frontend/assets/room/objects/book2/book2.glb
new file mode 100644
index 0000000000..2b26402f8c
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/book2.glb differ
diff --git a/packages/frontend/assets/room/objects/book2/texture.afdesign b/packages/frontend/assets/room/objects/book2/texture.afdesign
new file mode 100644
index 0000000000..b63771607a
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/texture.afdesign differ
diff --git a/packages/frontend/assets/room/objects/book2/texture.png b/packages/frontend/assets/room/objects/book2/texture.png
new file mode 100644
index 0000000000..5aa84f0340
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/texture.png differ
diff --git a/packages/frontend/assets/room/objects/book2/uv.png b/packages/frontend/assets/room/objects/book2/uv.png
new file mode 100644
index 0000000000..61c4fb0400
Binary files /dev/null and b/packages/frontend/assets/room/objects/book2/uv.png differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.blend b/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.blend
new file mode 100644
index 0000000000..3a528de32a
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.blend differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.glb b/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.glb
new file mode 100644
index 0000000000..bed372e94f
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box/cardboard-box.glb differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.blend b/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.blend
new file mode 100644
index 0000000000..5f146267ac
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.blend differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.glb b/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.glb
new file mode 100644
index 0000000000..85fcb5c0b6
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box2/cardboard-box2.glb differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box2/texture.png b/packages/frontend/assets/room/objects/cardboard-box2/texture.png
new file mode 100644
index 0000000000..e498d8f65b
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box2/texture.png differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box2/uv.png b/packages/frontend/assets/room/objects/cardboard-box2/uv.png
new file mode 100644
index 0000000000..d547843ee0
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box2/uv.png differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.blend b/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.blend
new file mode 100644
index 0000000000..00681a3cfd
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.blend differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.glb b/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.glb
new file mode 100644
index 0000000000..1ef0427689
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box3/cardboard-box3.glb differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box3/texture.png b/packages/frontend/assets/room/objects/cardboard-box3/texture.png
new file mode 100644
index 0000000000..56c914cb9d
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box3/texture.png differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box3/texture.xcf b/packages/frontend/assets/room/objects/cardboard-box3/texture.xcf
new file mode 100644
index 0000000000..7ffb3e3439
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box3/texture.xcf differ
diff --git a/packages/frontend/assets/room/objects/cardboard-box3/uv.png b/packages/frontend/assets/room/objects/cardboard-box3/uv.png
new file mode 100644
index 0000000000..797ac509db
Binary files /dev/null and b/packages/frontend/assets/room/objects/cardboard-box3/uv.png differ
diff --git a/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.blend b/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.blend
new file mode 100644
index 0000000000..750343d4f0
Binary files /dev/null and b/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.blend differ
diff --git a/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.glb b/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.glb
new file mode 100644
index 0000000000..3066a69e35
Binary files /dev/null and b/packages/frontend/assets/room/objects/carpet-stripe/carpet-stripe.glb differ
diff --git a/packages/frontend/assets/room/objects/chair/chair.blend b/packages/frontend/assets/room/objects/chair/chair.blend
new file mode 100644
index 0000000000..79c29a8401
Binary files /dev/null and b/packages/frontend/assets/room/objects/chair/chair.blend differ
diff --git a/packages/frontend/assets/room/objects/chair/chair.glb b/packages/frontend/assets/room/objects/chair/chair.glb
new file mode 100644
index 0000000000..08ee1a0bb0
Binary files /dev/null and b/packages/frontend/assets/room/objects/chair/chair.glb differ
diff --git a/packages/frontend/assets/room/objects/chair2/chair2.blend b/packages/frontend/assets/room/objects/chair2/chair2.blend
new file mode 100644
index 0000000000..c6a1acd96f
Binary files /dev/null and b/packages/frontend/assets/room/objects/chair2/chair2.blend differ
diff --git a/packages/frontend/assets/room/objects/chair2/chair2.glb b/packages/frontend/assets/room/objects/chair2/chair2.glb
new file mode 100644
index 0000000000..5ea2f3518b
Binary files /dev/null and b/packages/frontend/assets/room/objects/chair2/chair2.glb differ
diff --git a/packages/frontend/assets/room/objects/color-box/color-box.blend b/packages/frontend/assets/room/objects/color-box/color-box.blend
new file mode 100644
index 0000000000..f96a4ff766
Binary files /dev/null and b/packages/frontend/assets/room/objects/color-box/color-box.blend differ
diff --git a/packages/frontend/assets/room/objects/color-box/color-box.glb b/packages/frontend/assets/room/objects/color-box/color-box.glb
new file mode 100644
index 0000000000..43f2abcae8
Binary files /dev/null and b/packages/frontend/assets/room/objects/color-box/color-box.glb differ
diff --git a/packages/frontend/assets/room/objects/corkboard/corkboard.blend b/packages/frontend/assets/room/objects/corkboard/corkboard.blend
new file mode 100644
index 0000000000..9a7e1878cd
Binary files /dev/null and b/packages/frontend/assets/room/objects/corkboard/corkboard.blend differ
diff --git a/packages/frontend/assets/room/objects/corkboard/corkboard.glb b/packages/frontend/assets/room/objects/corkboard/corkboard.glb
new file mode 100644
index 0000000000..fee108fb91
Binary files /dev/null and b/packages/frontend/assets/room/objects/corkboard/corkboard.glb differ
diff --git a/packages/frontend/assets/room/objects/cube/cube.blend b/packages/frontend/assets/room/objects/cube/cube.blend
new file mode 100644
index 0000000000..1af5bf40a9
Binary files /dev/null and b/packages/frontend/assets/room/objects/cube/cube.blend differ
diff --git a/packages/frontend/assets/room/objects/cube/cube.glb b/packages/frontend/assets/room/objects/cube/cube.glb
new file mode 100644
index 0000000000..4ac8b6036d
Binary files /dev/null and b/packages/frontend/assets/room/objects/cube/cube.glb differ
diff --git a/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.blend b/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.blend
new file mode 100644
index 0000000000..37ca8868c7
Binary files /dev/null and b/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.blend differ
diff --git a/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.glb b/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.glb
new file mode 100644
index 0000000000..58efb1b3b4
Binary files /dev/null and b/packages/frontend/assets/room/objects/cup-noodle/cup-noodle.glb differ
diff --git a/packages/frontend/assets/room/objects/cup-noodle/noodle.png b/packages/frontend/assets/room/objects/cup-noodle/noodle.png
new file mode 100644
index 0000000000..1d74e0bbe7
Binary files /dev/null and b/packages/frontend/assets/room/objects/cup-noodle/noodle.png differ
diff --git a/packages/frontend/assets/room/objects/desk/desk.blend b/packages/frontend/assets/room/objects/desk/desk.blend
new file mode 100644
index 0000000000..c88d01f0b2
Binary files /dev/null and b/packages/frontend/assets/room/objects/desk/desk.blend differ
diff --git a/packages/frontend/assets/room/objects/desk/desk.glb b/packages/frontend/assets/room/objects/desk/desk.glb
new file mode 100644
index 0000000000..4a58513095
Binary files /dev/null and b/packages/frontend/assets/room/objects/desk/desk.glb differ
diff --git a/packages/frontend/assets/room/objects/doll-ai/doll-ai.blend b/packages/frontend/assets/room/objects/doll-ai/doll-ai.blend
new file mode 100644
index 0000000000..a912231ecb
Binary files /dev/null and b/packages/frontend/assets/room/objects/doll-ai/doll-ai.blend differ
diff --git a/packages/frontend/assets/room/objects/doll-ai/doll-ai.glb b/packages/frontend/assets/room/objects/doll-ai/doll-ai.glb
new file mode 100644
index 0000000000..ec55a7bd7b
Binary files /dev/null and b/packages/frontend/assets/room/objects/doll-ai/doll-ai.glb differ
diff --git a/packages/frontend/assets/room/objects/doll-ai/doll_ai_tex.png b/packages/frontend/assets/room/objects/doll-ai/doll_ai_tex.png
new file mode 100644
index 0000000000..370ca5f75b
Binary files /dev/null and b/packages/frontend/assets/room/objects/doll-ai/doll_ai_tex.png differ
diff --git a/packages/frontend/assets/room/objects/energy-drink/energy-drink.blend b/packages/frontend/assets/room/objects/energy-drink/energy-drink.blend
new file mode 100644
index 0000000000..65fc41273e
Binary files /dev/null and b/packages/frontend/assets/room/objects/energy-drink/energy-drink.blend differ
diff --git a/packages/frontend/assets/room/objects/energy-drink/energy-drink.glb b/packages/frontend/assets/room/objects/energy-drink/energy-drink.glb
new file mode 100644
index 0000000000..7fb1c27836
Binary files /dev/null and b/packages/frontend/assets/room/objects/energy-drink/energy-drink.glb differ
diff --git a/packages/frontend/assets/room/objects/energy-drink/texture.afdesign b/packages/frontend/assets/room/objects/energy-drink/texture.afdesign
new file mode 100644
index 0000000000..8c117a49b1
Binary files /dev/null and b/packages/frontend/assets/room/objects/energy-drink/texture.afdesign differ
diff --git a/packages/frontend/assets/room/objects/energy-drink/texture.png b/packages/frontend/assets/room/objects/energy-drink/texture.png
new file mode 100644
index 0000000000..484ca0f96f
Binary files /dev/null and b/packages/frontend/assets/room/objects/energy-drink/texture.png differ
diff --git a/packages/frontend/assets/room/objects/energy-drink/uv.png b/packages/frontend/assets/room/objects/energy-drink/uv.png
new file mode 100644
index 0000000000..2a3f20c999
Binary files /dev/null and b/packages/frontend/assets/room/objects/energy-drink/uv.png differ
diff --git a/packages/frontend/assets/room/objects/eraser/cover.png b/packages/frontend/assets/room/objects/eraser/cover.png
new file mode 100644
index 0000000000..932a3fc62e
Binary files /dev/null and b/packages/frontend/assets/room/objects/eraser/cover.png differ
diff --git a/packages/frontend/assets/room/objects/eraser/cover.psd b/packages/frontend/assets/room/objects/eraser/cover.psd
new file mode 100644
index 0000000000..c393337833
Binary files /dev/null and b/packages/frontend/assets/room/objects/eraser/cover.psd differ
diff --git a/packages/frontend/assets/room/objects/eraser/eraser-uv.png b/packages/frontend/assets/room/objects/eraser/eraser-uv.png
new file mode 100644
index 0000000000..89e4ea4c45
Binary files /dev/null and b/packages/frontend/assets/room/objects/eraser/eraser-uv.png differ
diff --git a/packages/frontend/assets/room/objects/eraser/eraser.blend b/packages/frontend/assets/room/objects/eraser/eraser.blend
new file mode 100644
index 0000000000..103c54fbae
Binary files /dev/null and b/packages/frontend/assets/room/objects/eraser/eraser.blend differ
diff --git a/packages/frontend/assets/room/objects/eraser/eraser.glb b/packages/frontend/assets/room/objects/eraser/eraser.glb
new file mode 100644
index 0000000000..016b60df20
Binary files /dev/null and b/packages/frontend/assets/room/objects/eraser/eraser.glb differ
diff --git a/packages/frontend/assets/room/objects/facial-tissue/facial-tissue-uv.png b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue-uv.png
new file mode 100644
index 0000000000..e3865ad15e
Binary files /dev/null and b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue-uv.png differ
diff --git a/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.blend b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.blend
new file mode 100644
index 0000000000..d59f87c1ee
Binary files /dev/null and b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.blend differ
diff --git a/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.glb b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.glb
new file mode 100644
index 0000000000..48b36ef347
Binary files /dev/null and b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.glb differ
diff --git a/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.png b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.png
new file mode 100644
index 0000000000..7cee4b1859
Binary files /dev/null and b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.png differ
diff --git a/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.psd b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.psd
new file mode 100644
index 0000000000..cd59fc007b
Binary files /dev/null and b/packages/frontend/assets/room/objects/facial-tissue/facial-tissue.psd differ
diff --git a/packages/frontend/assets/room/objects/fan/fan.blend b/packages/frontend/assets/room/objects/fan/fan.blend
new file mode 100644
index 0000000000..8c8106e5fe
Binary files /dev/null and b/packages/frontend/assets/room/objects/fan/fan.blend differ
diff --git a/packages/frontend/assets/room/objects/fan/fan.glb b/packages/frontend/assets/room/objects/fan/fan.glb
new file mode 100644
index 0000000000..d9367f3534
Binary files /dev/null and b/packages/frontend/assets/room/objects/fan/fan.glb differ
diff --git a/packages/frontend/assets/room/objects/holo-display/holo-display.blend b/packages/frontend/assets/room/objects/holo-display/holo-display.blend
new file mode 100644
index 0000000000..56d2e1f819
Binary files /dev/null and b/packages/frontend/assets/room/objects/holo-display/holo-display.blend differ
diff --git a/packages/frontend/assets/room/objects/holo-display/holo-display.glb b/packages/frontend/assets/room/objects/holo-display/holo-display.glb
new file mode 100644
index 0000000000..4d042a59b3
Binary files /dev/null and b/packages/frontend/assets/room/objects/holo-display/holo-display.glb differ
diff --git a/packages/frontend/assets/room/objects/holo-display/ray-uv.png b/packages/frontend/assets/room/objects/holo-display/ray-uv.png
new file mode 100644
index 0000000000..aa7e817e0f
Binary files /dev/null and b/packages/frontend/assets/room/objects/holo-display/ray-uv.png differ
diff --git a/packages/frontend/assets/room/objects/holo-display/ray.png b/packages/frontend/assets/room/objects/holo-display/ray.png
new file mode 100644
index 0000000000..6a5d24e143
Binary files /dev/null and b/packages/frontend/assets/room/objects/holo-display/ray.png differ
diff --git a/packages/frontend/assets/room/objects/keyboard/keyboard.blend b/packages/frontend/assets/room/objects/keyboard/keyboard.blend
new file mode 100644
index 0000000000..ab33d134b3
Binary files /dev/null and b/packages/frontend/assets/room/objects/keyboard/keyboard.blend differ
diff --git a/packages/frontend/assets/room/objects/keyboard/keyboard.glb b/packages/frontend/assets/room/objects/keyboard/keyboard.glb
new file mode 100644
index 0000000000..15dc69f47a
Binary files /dev/null and b/packages/frontend/assets/room/objects/keyboard/keyboard.glb differ
diff --git a/packages/frontend/assets/room/objects/low-table/low-table.blend b/packages/frontend/assets/room/objects/low-table/low-table.blend
new file mode 100644
index 0000000000..e1592174d9
Binary files /dev/null and b/packages/frontend/assets/room/objects/low-table/low-table.blend differ
diff --git a/packages/frontend/assets/room/objects/low-table/low-table.glb b/packages/frontend/assets/room/objects/low-table/low-table.glb
new file mode 100644
index 0000000000..c69bf35d7b
Binary files /dev/null and b/packages/frontend/assets/room/objects/low-table/low-table.glb differ
diff --git a/packages/frontend/assets/room/objects/mat/mat.blend b/packages/frontend/assets/room/objects/mat/mat.blend
new file mode 100644
index 0000000000..a1e1a68c55
Binary files /dev/null and b/packages/frontend/assets/room/objects/mat/mat.blend differ
diff --git a/packages/frontend/assets/room/objects/mat/mat.glb b/packages/frontend/assets/room/objects/mat/mat.glb
new file mode 100644
index 0000000000..87ccd44e1a
Binary files /dev/null and b/packages/frontend/assets/room/objects/mat/mat.glb differ
diff --git a/packages/frontend/assets/room/objects/milk/milk-uv.png b/packages/frontend/assets/room/objects/milk/milk-uv.png
new file mode 100644
index 0000000000..258fd54638
Binary files /dev/null and b/packages/frontend/assets/room/objects/milk/milk-uv.png differ
diff --git a/packages/frontend/assets/room/objects/milk/milk.blend b/packages/frontend/assets/room/objects/milk/milk.blend
new file mode 100644
index 0000000000..2df508d5b9
Binary files /dev/null and b/packages/frontend/assets/room/objects/milk/milk.blend differ
diff --git a/packages/frontend/assets/room/objects/milk/milk.glb b/packages/frontend/assets/room/objects/milk/milk.glb
new file mode 100644
index 0000000000..b335fe3d02
Binary files /dev/null and b/packages/frontend/assets/room/objects/milk/milk.glb differ
diff --git a/packages/frontend/assets/room/objects/milk/milk.png b/packages/frontend/assets/room/objects/milk/milk.png
new file mode 100644
index 0000000000..35181c8c8c
Binary files /dev/null and b/packages/frontend/assets/room/objects/milk/milk.png differ
diff --git a/packages/frontend/assets/room/objects/milk/milk.psd b/packages/frontend/assets/room/objects/milk/milk.psd
new file mode 100644
index 0000000000..f31e439277
Binary files /dev/null and b/packages/frontend/assets/room/objects/milk/milk.psd differ
diff --git a/packages/frontend/assets/room/objects/monitor/monitor.blend b/packages/frontend/assets/room/objects/monitor/monitor.blend
new file mode 100644
index 0000000000..6c042ccdd8
Binary files /dev/null and b/packages/frontend/assets/room/objects/monitor/monitor.blend differ
diff --git a/packages/frontend/assets/room/objects/monitor/monitor.glb b/packages/frontend/assets/room/objects/monitor/monitor.glb
new file mode 100644
index 0000000000..fc33286a15
Binary files /dev/null and b/packages/frontend/assets/room/objects/monitor/monitor.glb differ
diff --git a/packages/frontend/assets/room/objects/monitor/monitor.psd b/packages/frontend/assets/room/objects/monitor/monitor.psd
new file mode 100644
index 0000000000..57afff9cd9
Binary files /dev/null and b/packages/frontend/assets/room/objects/monitor/monitor.psd differ
diff --git a/packages/frontend/assets/room/objects/monitor/screen-uv.png b/packages/frontend/assets/room/objects/monitor/screen-uv.png
new file mode 100644
index 0000000000..35f74de8aa
Binary files /dev/null and b/packages/frontend/assets/room/objects/monitor/screen-uv.png differ
diff --git a/packages/frontend/assets/room/objects/monitor/screen.jpg b/packages/frontend/assets/room/objects/monitor/screen.jpg
new file mode 100644
index 0000000000..4004a1ede9
Binary files /dev/null and b/packages/frontend/assets/room/objects/monitor/screen.jpg differ
diff --git a/packages/frontend/assets/room/objects/moon/moon.blend b/packages/frontend/assets/room/objects/moon/moon.blend
new file mode 100644
index 0000000000..4ff3deab8e
Binary files /dev/null and b/packages/frontend/assets/room/objects/moon/moon.blend differ
diff --git a/packages/frontend/assets/room/objects/moon/moon.glb b/packages/frontend/assets/room/objects/moon/moon.glb
new file mode 100644
index 0000000000..07fa7e4c02
Binary files /dev/null and b/packages/frontend/assets/room/objects/moon/moon.glb differ
diff --git a/packages/frontend/assets/room/objects/moon/moon.jpg b/packages/frontend/assets/room/objects/moon/moon.jpg
new file mode 100644
index 0000000000..8988ac64b9
Binary files /dev/null and b/packages/frontend/assets/room/objects/moon/moon.jpg differ
diff --git a/packages/frontend/assets/room/objects/mousepad/mousepad.blend b/packages/frontend/assets/room/objects/mousepad/mousepad.blend
new file mode 100644
index 0000000000..14bd139c94
Binary files /dev/null and b/packages/frontend/assets/room/objects/mousepad/mousepad.blend differ
diff --git a/packages/frontend/assets/room/objects/mousepad/mousepad.glb b/packages/frontend/assets/room/objects/mousepad/mousepad.glb
new file mode 100644
index 0000000000..681ada49cd
Binary files /dev/null and b/packages/frontend/assets/room/objects/mousepad/mousepad.glb differ
diff --git a/packages/frontend/assets/room/objects/mug/mug.blend b/packages/frontend/assets/room/objects/mug/mug.blend
new file mode 100644
index 0000000000..95f8c71791
Binary files /dev/null and b/packages/frontend/assets/room/objects/mug/mug.blend differ
diff --git a/packages/frontend/assets/room/objects/mug/mug.glb b/packages/frontend/assets/room/objects/mug/mug.glb
new file mode 100644
index 0000000000..df5ad06b32
Binary files /dev/null and b/packages/frontend/assets/room/objects/mug/mug.glb differ
diff --git a/packages/frontend/assets/room/objects/pc/motherboard-uv.png b/packages/frontend/assets/room/objects/pc/motherboard-uv.png
new file mode 100644
index 0000000000..355009fe7c
Binary files /dev/null and b/packages/frontend/assets/room/objects/pc/motherboard-uv.png differ
diff --git a/packages/frontend/assets/room/objects/pc/motherboard-uv.psd b/packages/frontend/assets/room/objects/pc/motherboard-uv.psd
new file mode 100644
index 0000000000..971f33f79e
Binary files /dev/null and b/packages/frontend/assets/room/objects/pc/motherboard-uv.psd differ
diff --git a/packages/frontend/assets/room/objects/pc/motherboard.jpg b/packages/frontend/assets/room/objects/pc/motherboard.jpg
new file mode 100644
index 0000000000..d894e4efcf
Binary files /dev/null and b/packages/frontend/assets/room/objects/pc/motherboard.jpg differ
diff --git a/packages/frontend/assets/room/objects/pc/pc.blend b/packages/frontend/assets/room/objects/pc/pc.blend
new file mode 100644
index 0000000000..13dfec6ccc
Binary files /dev/null and b/packages/frontend/assets/room/objects/pc/pc.blend differ
diff --git a/packages/frontend/assets/room/objects/pc/pc.glb b/packages/frontend/assets/room/objects/pc/pc.glb
new file mode 100644
index 0000000000..44a48b18ae
Binary files /dev/null and b/packages/frontend/assets/room/objects/pc/pc.glb differ
diff --git a/packages/frontend/assets/room/objects/pencil/pencil.blend b/packages/frontend/assets/room/objects/pencil/pencil.blend
new file mode 100644
index 0000000000..0fc6bdd776
Binary files /dev/null and b/packages/frontend/assets/room/objects/pencil/pencil.blend differ
diff --git a/packages/frontend/assets/room/objects/pencil/pencil.glb b/packages/frontend/assets/room/objects/pencil/pencil.glb
new file mode 100644
index 0000000000..a938b5cdcc
Binary files /dev/null and b/packages/frontend/assets/room/objects/pencil/pencil.glb differ
diff --git a/packages/frontend/assets/room/objects/photoframe/photo-uv.png b/packages/frontend/assets/room/objects/photoframe/photo-uv.png
new file mode 100644
index 0000000000..9b94906413
Binary files /dev/null and b/packages/frontend/assets/room/objects/photoframe/photo-uv.png differ
diff --git a/packages/frontend/assets/room/objects/photoframe/photo.jpg b/packages/frontend/assets/room/objects/photoframe/photo.jpg
new file mode 100644
index 0000000000..af14f0f36a
Binary files /dev/null and b/packages/frontend/assets/room/objects/photoframe/photo.jpg differ
diff --git a/packages/frontend/assets/room/objects/photoframe/photoframe.blend b/packages/frontend/assets/room/objects/photoframe/photoframe.blend
new file mode 100644
index 0000000000..4224cde45b
Binary files /dev/null and b/packages/frontend/assets/room/objects/photoframe/photoframe.blend differ
diff --git a/packages/frontend/assets/room/objects/photoframe/photoframe.glb b/packages/frontend/assets/room/objects/photoframe/photoframe.glb
new file mode 100644
index 0000000000..4255a77de6
Binary files /dev/null and b/packages/frontend/assets/room/objects/photoframe/photoframe.glb differ
diff --git a/packages/frontend/assets/room/objects/piano/piano.blend b/packages/frontend/assets/room/objects/piano/piano.blend
new file mode 100644
index 0000000000..7653cdf672
Binary files /dev/null and b/packages/frontend/assets/room/objects/piano/piano.blend differ
diff --git a/packages/frontend/assets/room/objects/piano/piano.glb b/packages/frontend/assets/room/objects/piano/piano.glb
new file mode 100644
index 0000000000..7242e78ceb
Binary files /dev/null and b/packages/frontend/assets/room/objects/piano/piano.glb differ
diff --git a/packages/frontend/assets/room/objects/pinguin/pinguin.blend b/packages/frontend/assets/room/objects/pinguin/pinguin.blend
new file mode 100644
index 0000000000..514c713e4c
Binary files /dev/null and b/packages/frontend/assets/room/objects/pinguin/pinguin.blend differ
diff --git a/packages/frontend/assets/room/objects/pinguin/pinguin.glb b/packages/frontend/assets/room/objects/pinguin/pinguin.glb
new file mode 100644
index 0000000000..6df34c06e9
Binary files /dev/null and b/packages/frontend/assets/room/objects/pinguin/pinguin.glb differ
diff --git a/packages/frontend/assets/room/objects/plant/plant-soil-uv.png b/packages/frontend/assets/room/objects/plant/plant-soil-uv.png
new file mode 100644
index 0000000000..d4971a896c
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant/plant-soil-uv.png differ
diff --git a/packages/frontend/assets/room/objects/plant/plant-soil.png b/packages/frontend/assets/room/objects/plant/plant-soil.png
new file mode 100644
index 0000000000..e79ccd240e
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant/plant-soil.png differ
diff --git a/packages/frontend/assets/room/objects/plant/plant-soil.psd b/packages/frontend/assets/room/objects/plant/plant-soil.psd
new file mode 100644
index 0000000000..1457b7ea5b
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant/plant-soil.psd differ
diff --git a/packages/frontend/assets/room/objects/plant/plant.blend b/packages/frontend/assets/room/objects/plant/plant.blend
new file mode 100644
index 0000000000..aa38c7b54e
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant/plant.blend differ
diff --git a/packages/frontend/assets/room/objects/plant/plant.glb b/packages/frontend/assets/room/objects/plant/plant.glb
new file mode 100644
index 0000000000..38422b4a9b
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant/plant.glb differ
diff --git a/packages/frontend/assets/room/objects/plant2/plant2.blend b/packages/frontend/assets/room/objects/plant2/plant2.blend
new file mode 100644
index 0000000000..6592c5d98d
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant2/plant2.blend differ
diff --git a/packages/frontend/assets/room/objects/plant2/plant2.glb b/packages/frontend/assets/room/objects/plant2/plant2.glb
new file mode 100644
index 0000000000..223e6f5834
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant2/plant2.glb differ
diff --git a/packages/frontend/assets/room/objects/plant2/soil.png b/packages/frontend/assets/room/objects/plant2/soil.png
new file mode 100644
index 0000000000..e79ccd240e
Binary files /dev/null and b/packages/frontend/assets/room/objects/plant2/soil.png differ
diff --git a/packages/frontend/assets/room/objects/poster-h/poster-h.blend b/packages/frontend/assets/room/objects/poster-h/poster-h.blend
new file mode 100644
index 0000000000..40f944f3c1
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-h/poster-h.blend differ
diff --git a/packages/frontend/assets/room/objects/poster-h/poster-h.glb b/packages/frontend/assets/room/objects/poster-h/poster-h.glb
new file mode 100644
index 0000000000..c6032c1009
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-h/poster-h.glb differ
diff --git a/packages/frontend/assets/room/objects/poster-h/uv.png b/packages/frontend/assets/room/objects/poster-h/uv.png
new file mode 100644
index 0000000000..f854231e0b
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-h/uv.png differ
diff --git a/packages/frontend/assets/room/objects/poster-v/poster-v.blend b/packages/frontend/assets/room/objects/poster-v/poster-v.blend
new file mode 100644
index 0000000000..07fe971634
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-v/poster-v.blend differ
diff --git a/packages/frontend/assets/room/objects/poster-v/poster-v.glb b/packages/frontend/assets/room/objects/poster-v/poster-v.glb
new file mode 100644
index 0000000000..6e3782f193
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-v/poster-v.glb differ
diff --git a/packages/frontend/assets/room/objects/poster-v/uv.png b/packages/frontend/assets/room/objects/poster-v/uv.png
new file mode 100644
index 0000000000..7bb2bf809e
Binary files /dev/null and b/packages/frontend/assets/room/objects/poster-v/uv.png differ
diff --git a/packages/frontend/assets/room/objects/pudding/pudding.blend b/packages/frontend/assets/room/objects/pudding/pudding.blend
new file mode 100644
index 0000000000..bba40ce161
Binary files /dev/null and b/packages/frontend/assets/room/objects/pudding/pudding.blend differ
diff --git a/packages/frontend/assets/room/objects/pudding/pudding.glb b/packages/frontend/assets/room/objects/pudding/pudding.glb
new file mode 100644
index 0000000000..06c9ed80cc
Binary files /dev/null and b/packages/frontend/assets/room/objects/pudding/pudding.glb differ
diff --git a/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.blend b/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.blend
new file mode 100644
index 0000000000..6c09067e78
Binary files /dev/null and b/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.blend differ
diff --git a/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.glb b/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.glb
new file mode 100644
index 0000000000..d640df9b06
Binary files /dev/null and b/packages/frontend/assets/room/objects/rubik-cube/rubik-cube.glb differ
diff --git a/packages/frontend/assets/room/objects/server/rack-uv.png b/packages/frontend/assets/room/objects/server/rack-uv.png
new file mode 100644
index 0000000000..65bdb0ffd9
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/rack-uv.png differ
diff --git a/packages/frontend/assets/room/objects/server/rack.png b/packages/frontend/assets/room/objects/server/rack.png
new file mode 100644
index 0000000000..b851295cfa
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/rack.png differ
diff --git a/packages/frontend/assets/room/objects/server/server.blend b/packages/frontend/assets/room/objects/server/server.blend
new file mode 100644
index 0000000000..6675dfbdc2
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/server.blend differ
diff --git a/packages/frontend/assets/room/objects/server/server.glb b/packages/frontend/assets/room/objects/server/server.glb
new file mode 100644
index 0000000000..a8b530a2d2
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/server.glb differ
diff --git a/packages/frontend/assets/room/objects/server/server.png b/packages/frontend/assets/room/objects/server/server.png
new file mode 100644
index 0000000000..8e9a0d716c
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/server.png differ
diff --git a/packages/frontend/assets/room/objects/server/uv.png b/packages/frontend/assets/room/objects/server/uv.png
new file mode 100644
index 0000000000..ca2e747d16
Binary files /dev/null and b/packages/frontend/assets/room/objects/server/uv.png differ
diff --git a/packages/frontend/assets/room/objects/sofa/sofa.blend b/packages/frontend/assets/room/objects/sofa/sofa.blend
new file mode 100644
index 0000000000..fb5aa51a2c
Binary files /dev/null and b/packages/frontend/assets/room/objects/sofa/sofa.blend differ
diff --git a/packages/frontend/assets/room/objects/sofa/sofa.glb b/packages/frontend/assets/room/objects/sofa/sofa.glb
new file mode 100644
index 0000000000..6ce77d94ac
Binary files /dev/null and b/packages/frontend/assets/room/objects/sofa/sofa.glb differ
diff --git a/packages/frontend/assets/room/objects/spiral/spiral.blend b/packages/frontend/assets/room/objects/spiral/spiral.blend
new file mode 100644
index 0000000000..9d3be77bce
Binary files /dev/null and b/packages/frontend/assets/room/objects/spiral/spiral.blend differ
diff --git a/packages/frontend/assets/room/objects/spiral/spiral.glb b/packages/frontend/assets/room/objects/spiral/spiral.glb
new file mode 100644
index 0000000000..ee8e3c23b1
Binary files /dev/null and b/packages/frontend/assets/room/objects/spiral/spiral.glb differ
diff --git a/packages/frontend/assets/room/objects/tv/screen-uv.png b/packages/frontend/assets/room/objects/tv/screen-uv.png
new file mode 100644
index 0000000000..4bb74f031f
Binary files /dev/null and b/packages/frontend/assets/room/objects/tv/screen-uv.png differ
diff --git a/packages/frontend/assets/room/objects/tv/tv.blend b/packages/frontend/assets/room/objects/tv/tv.blend
new file mode 100644
index 0000000000..490e298e7b
Binary files /dev/null and b/packages/frontend/assets/room/objects/tv/tv.blend differ
diff --git a/packages/frontend/assets/room/objects/tv/tv.glb b/packages/frontend/assets/room/objects/tv/tv.glb
new file mode 100644
index 0000000000..b9bd23896b
Binary files /dev/null and b/packages/frontend/assets/room/objects/tv/tv.glb differ
diff --git a/packages/frontend/assets/room/objects/wall-clock/wall-clock.blend b/packages/frontend/assets/room/objects/wall-clock/wall-clock.blend
new file mode 100644
index 0000000000..0a61c8f01e
Binary files /dev/null and b/packages/frontend/assets/room/objects/wall-clock/wall-clock.blend differ
diff --git a/packages/frontend/assets/room/objects/wall-clock/wall-clock.glb b/packages/frontend/assets/room/objects/wall-clock/wall-clock.glb
new file mode 100644
index 0000000000..b9f0093a8d
Binary files /dev/null and b/packages/frontend/assets/room/objects/wall-clock/wall-clock.glb differ
diff --git a/packages/frontend/assets/room/rooms/default.glb b/packages/frontend/assets/room/rooms/default.glb
new file mode 100644
index 0000000000..9fecf0a38e
Binary files /dev/null and b/packages/frontend/assets/room/rooms/default.glb differ
diff --git a/packages/frontend/assets/room/steam.af b/packages/frontend/assets/room/steam.af
new file mode 100644
index 0000000000..178c251762
Binary files /dev/null and b/packages/frontend/assets/room/steam.af differ
diff --git a/packages/frontend/assets/room/steam.png b/packages/frontend/assets/room/steam.png
new file mode 100644
index 0000000000..d088cd71cf
Binary files /dev/null and b/packages/frontend/assets/room/steam.png differ
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index fff2b6dcf2..a59aa2c30f 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -17,6 +17,9 @@
},
"dependencies": {
"@analytics/google-analytics": "1.1.0",
+ "@babylonjs/core": "8.49.6",
+ "@babylonjs/loaders": "8.49.6",
+ "@babylonjs/materials": "8.49.6",
"@discordapp/twemoji": "16.0.1",
"@github/webauthn-json": "2.1.1",
"@mcaptcha/core-glue": "0.1.0-alpha-5",
diff --git a/packages/frontend/src/pages/room.vue b/packages/frontend/src/pages/room.vue
new file mode 100644
index 0000000000..913231776e
--- /dev/null
+++ b/packages/frontend/src/pages/room.vue
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/router.definition.ts b/packages/frontend/src/router.definition.ts
index d59c9d1c6f..4241f79dea 100644
--- a/packages/frontend/src/router.definition.ts
+++ b/packages/frontend/src/router.definition.ts
@@ -594,6 +594,9 @@ export const ROUTE_DEF = [{
path: '/qr',
component: page(() => import('@/pages/qr.vue')),
loginRequired: true,
+}, {
+ path: '/room',
+ component: page(() => import('@/pages/room.vue')),
}, {
path: '/debug',
component: page(() => import('@/pages/debug.vue')),
diff --git a/packages/frontend/src/utility/room/engine.ts b/packages/frontend/src/utility/room/engine.ts
new file mode 100644
index 0000000000..eb80d36cb0
--- /dev/null
+++ b/packages/frontend/src/utility/room/engine.ts
@@ -0,0 +1,487 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import * as BABYLON from '@babylonjs/core';
+import { AxesViewer } from '@babylonjs/core/Debug/axesViewer';
+import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic';
+import { MmdOutlineRenderer } from './outlineRenderer.ts';
+
+type RoomDef = {
+ roomType: 'default';
+ objects: {
+ id: string;
+ type: string;
+ position: [number, number, number];
+ rotation: [number, number, number];
+ parent: string | null;
+ }[];
+};
+
+const OBJECTS = {
+ plant: {
+ placement: 'top',
+ },
+ mug: {
+ placement: 'top',
+ },
+ stickyNote: {
+ placement: 'side',
+ },
+};
+
+function vecToLocal(vector: BABYLON.Vector3, mesh: BABYLON.Mesh): BABYLON.Vector3 {
+ const m = mesh.getWorldMatrix();
+ const v = BABYLON.Vector3.TransformCoordinates(vector, m);
+ return v;
+}
+
+const _assumedFramesPerSecond = 60;
+
+class HorizontalCameraKeyboardMoveInput extends BABYLON.BaseCameraPointersInput {
+ public camera: BABYLON.FreeCamera;
+ private engine: BABYLON.AbstractEngine;
+ private scene: BABYLON.Scene;
+ moveSpeed = 6 / _assumedFramesPerSecond;
+ preShift = false;
+ codes = [];
+ codesUp = ['KeyW'];
+ codesDown = ['KeyS'];
+ codesLeft = ['KeyA'];
+ codesRight = ['KeyD'];
+ onCanvasBlurObserver = null;
+ onKeyboardObserver = null;
+
+ constructor(camera: BABYLON.UniversalCamera) {
+ super();
+ this.camera = camera;
+ this.scene = this.camera.getScene();
+ this.engine = this.scene.getEngine();
+ }
+
+ attachControl() {
+ if (this.onCanvasBlurObserver) {
+ return;
+ }
+
+ this.onCanvasBlurObserver = this.engine.onCanvasBlurObservable.add(() => {
+ this.codes = [];
+ });
+
+ this.onKeyboardObserver = this.scene.onKeyboardObservable.add(({ event, type }) => {
+ const { code, shiftKey } = event;
+ this.preShift = shiftKey;
+
+ if (type === BABYLON.KeyboardEventTypes.KEYDOWN) {
+ if (this.codesUp.indexOf(code) >= 0 ||
+ this.codesDown.indexOf(code) >= 0 ||
+ this.codesLeft.indexOf(code) >= 0 ||
+ this.codesRight.indexOf(code) >= 0) {
+ const index = this.codes.findIndex(v => v.code === code);
+ if (index < 0) { // 存在しなかったら追加する
+ this.codes.push({ code });
+ }
+ event.preventDefault();
+ (event as KeyboardEvent).stopPropagation();
+ }
+ } else {
+ if (this.codesUp.indexOf(code) >= 0 ||
+ this.codesDown.indexOf(code) >= 0 ||
+ this.codesLeft.indexOf(code) >= 0 ||
+ this.codesRight.indexOf(code) >= 0) {
+ const index = this.codes.findIndex(v => v.code === code);
+ if (index >= 0) { // 存在したら削除する
+ this.codes.splice(index, 1);
+ }
+ event.preventDefault();
+ (event as KeyboardEvent).stopPropagation();
+ }
+ }
+ });
+ }
+
+ detachControl() {
+ this.codes = [];
+
+ if (this.onKeyboardObserver) this.scene.onKeyboardObservable.remove(this.onKeyboardObserver);
+ if (this.onCanvasBlurObserver) this.engine.onCanvasBlurObservable.remove(this.onCanvasBlurObserver);
+ this.onKeyboardObserver = null;
+ this.onCanvasBlurObserver = null;
+ }
+
+ checkInputs() {
+ if (!this.onKeyboardObserver) {
+ return;
+ }
+ for (let index = 0; index < this.codes.length; index++) {
+ const { code } = this.codes[index];
+
+ const local = new BABYLON.Vector3();
+ if (this.codesLeft.indexOf(code) >= 0) {
+ local.x += -1;
+ } else if (this.codesUp.indexOf(code) >= 0) {
+ local.z += 1;
+ } else if (this.codesRight.indexOf(code) >= 0) {
+ local.x += 1;
+ } else if (this.codesDown.indexOf(code) >= 0) {
+ local.z += -1;
+ }
+
+ if (local.length() === 0) {
+ continue;
+ }
+
+ const dir = this.camera.getDirection(local.normalize());
+ dir.y = 0;
+ dir.normalize();
+ const rate = this.preShift ? 3 : 1;
+ const move = dir.scale(this.moveSpeed * rate);
+ this.camera.cameraDirection.addInPlace(move);
+ }
+ }
+
+ getClassName() {
+ return 'HorizontalCameraKeyboardMoveInput';
+ }
+
+ getSimpleName() {
+ return 'horizontalkeyboard';
+ }
+}
+
+export class RoomEngine {
+ private canvas: HTMLCanvasElement;
+ private engine: BABYLON.Engine;
+ private scene: BABYLON.Scene;
+ private shadowGenerator1: BABYLON.ShadowGenerator;
+ private shadowGenerator2: BABYLON.ShadowGenerator;
+ private camera: BABYLON.UniversalCamera;
+ private ROOM_SIZE = 300/*cm*/;
+ private intervalIds: number[] = [];
+ private objects: Map = new Map();
+ private grabbing: BABYLON.AbstractMesh | null = null;
+ private grabbingStartDistance: number | null = null;
+ private grabbingGhost: BABYLON.AbstractMesh | null = null;
+ public highlightedObjectId: string | null = null;
+
+ public moveForward = false;
+ public moveBackward = false;
+ public moveLeft = false;
+ public moveRight = false;
+
+ constructor(options: {
+ canvas: HTMLCanvasElement;
+ }) {
+ registerBuiltInLoaders();
+
+ this.canvas = options.canvas;
+ this.engine = new BABYLON.Engine(options.canvas, false);
+ this.scene = new BABYLON.Scene(this.engine);
+ //this.scene.autoClear = false;
+ //this.scene.clearColor = new BABYLON.Color4(0.05, 0.1, 0.2, 0);
+ this.scene.collisionsEnabled = true;
+
+ //new MmdOutlineRenderer(this.scene);
+
+ //this.camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 2.5, 300/*cm*/, new BABYLON.Vector3(0, 90/*cm*/, 0), this.scene);
+ //this.camera.attachControl(this.canvas, true);
+ //this.camera.minZ = 1/*cm*/;
+ //this.camera.maxZ = 1500/*cm*/;
+ //this.camera.fov = 0.5;
+
+ this.camera = new BABYLON.UniversalCamera('camera', new BABYLON.Vector3(0, 130/*cm*/, 0/*cm*/), this.scene);
+ this.camera.inputs.removeByType('FreeCameraKeyboardMoveInput');
+ this.camera.inputs.add(new HorizontalCameraKeyboardMoveInput(this.camera));
+ this.camera.attachControl(this.canvas);
+ this.camera.minZ = 1/*cm*/;
+ this.camera.maxZ = 1500/*cm*/;
+ this.camera.fov = 1;
+ this.camera.ellipsoid = new BABYLON.Vector3(15/*cm*/, 65/*cm*/, 15/*cm*/);
+ this.camera.checkCollisions = true;
+ this.camera.applyGravity = true;
+ this.camera.needMoveForGravity = true;
+
+ const floor = BABYLON.MeshBuilder.CreateGround('floor', { width: this.ROOM_SIZE, height: this.ROOM_SIZE }, this.scene);
+ floor.isVisible = false;
+ floor.checkCollisions = true;
+ const wall1 = BABYLON.MeshBuilder.CreateBox('wall1', { width: this.ROOM_SIZE, height: 200/*cm*/, depth: 2/*cm*/ }, this.scene);
+ wall1.position = new BABYLON.Vector3(0, 100/*cm*/, -this.ROOM_SIZE / 2);
+ wall1.isVisible = false;
+ wall1.checkCollisions = true;
+ const wall2 = BABYLON.MeshBuilder.CreateBox('wall2', { width: this.ROOM_SIZE, height: 200/*cm*/, depth: 2/*cm*/ }, this.scene);
+ wall2.position = new BABYLON.Vector3(0, 100/*cm*/, this.ROOM_SIZE / 2);
+ wall2.isVisible = false;
+ wall2.checkCollisions = true;
+ const wall3 = BABYLON.MeshBuilder.CreateBox('wall3', { width: 2/*cm*/, height: 200/*cm*/, depth: this.ROOM_SIZE }, this.scene);
+ wall3.position = new BABYLON.Vector3(-this.ROOM_SIZE / 2, 100/*cm*/, 0);
+ wall3.isVisible = false;
+ wall3.checkCollisions = true;
+ const wall4 = BABYLON.MeshBuilder.CreateBox('wall4', { width: 2/*cm*/, height: 200/*cm*/, depth: this.ROOM_SIZE }, this.scene);
+ wall4.position = new BABYLON.Vector3(this.ROOM_SIZE / 2, 100/*cm*/, 0);
+ wall4.isVisible = false;
+ wall4.checkCollisions = true;
+
+ const ambientLight = new BABYLON.HemisphericLight('ambientLight', new BABYLON.Vector3(0, 1, -0.5), this.scene);
+ ambientLight.diffuse = new BABYLON.Color3(1.0, 1.0, 1.0);
+ ambientLight.intensity = 0.5;
+
+ const roomLight = new BABYLON.SpotLight('roomLight', new BABYLON.Vector3(0, 250/*cm*/, 0), new BABYLON.Vector3(0, -1, 0), 4, 8, this.scene);
+ roomLight.diffuse = new BABYLON.Color3(1.0, 0.9, 0.8);
+ roomLight.intensity = 150000;
+ roomLight.shadowMinZ = 10/*cm*/;
+ roomLight.shadowMaxZ = 300/*cm*/;
+
+ this.shadowGenerator1 = new BABYLON.ShadowGenerator(2048, roomLight);
+ this.shadowGenerator1.forceBackFacesOnly = true;
+ this.shadowGenerator1.bias = 0.0001;
+ this.shadowGenerator1.usePercentageCloserFiltering = true;
+ this.shadowGenerator1.useContactHardeningShadow = true;
+
+ const sunLight = new BABYLON.DirectionalLight('sunLight', new BABYLON.Vector3(0.2, -1, -1), this.scene);
+ sunLight.position = new BABYLON.Vector3(-20, 1000, 1000);
+ sunLight.diffuse = new BABYLON.Color3(1.0, 0.9, 0.8);
+ sunLight.intensity = 2;
+
+ this.shadowGenerator2 = new BABYLON.ShadowGenerator(4092, sunLight);
+ this.shadowGenerator2.forceBackFacesOnly = true;
+ this.shadowGenerator2.bias = 0.0001;
+ this.shadowGenerator2.usePercentageCloserFiltering = true;
+ this.shadowGenerator2.usePoissonSampling = true;
+
+ {
+ const postProcess = new BABYLON.ImageProcessingPostProcess('processing', 1.0, this.camera);
+ postProcess.exposure = 2;
+ postProcess.contrast = 0.9;
+ //const curve = new BABYLON.ColorCurves();
+ //curve.highlightsHue = 40;
+ //curve.highlightsDensity = 50;
+ //curve.highlightsSaturation = 40;
+ //curve.shadowsHue = 200;
+ //curve.shadowsDensity = 100;
+ //curve.shadowsSaturation = 40;
+ //postProcess.colorCurvesEnabled = true;
+ //postProcess.colorCurves = curve;
+ }
+
+ this.canvas.addEventListener('click', (ev) => {
+ const mesh = this.scene.pick(this.scene.pointerX, this.scene.pointerY)?.pickedMesh;
+ if (mesh != null) {
+ const oid = mesh.metadata.objectId;
+ if (oid != null && this.objects.has(oid)) {
+ const o = this.objects.get(oid)!;
+ // focus camera
+ this.camera.setTarget(o.position);
+ }
+ }
+ });
+
+ if (_DEV_) {
+ new AxesViewer(this.scene, 5);
+
+ //const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 30 }, this.scene);
+ //sphere.position = new BABYLON.Vector3(0, 30, 0);
+ //sphere.receiveShadows = true;
+ //this.shadowGenerator1.addShadowCaster(sphere);
+ //this.shadowGenerator2.addShadowCaster(sphere);
+ }
+ }
+
+ public async init(def: RoomDef) {
+ await this.loadRoomModel(def.roomType);
+
+ for (const objDef of def.objects) {
+ this.loadObject(objDef.id, objDef.type, new BABYLON.Vector3(...objDef.position), new BABYLON.Vector3(...objDef.rotation));
+ }
+
+ function isIntersectXZ(a: BABYLON.BoundingBox, b: BABYLON.BoundingBox): boolean {
+ return (a.minimumWorld.x <= b.maximumWorld.x &&
+ a.maximumWorld.x >= b.minimumWorld.x) &&
+ (a.minimumWorld.z <= b.maximumWorld.z &&
+ a.maximumWorld.z >= b.minimumWorld.z);
+ }
+
+ this.intervalIds.push(window.setInterval(() => {
+ if (this.grabbing != null) {
+ const dir = this.camera.getDirection(BABYLON.Axis.Z);
+ this.grabbingGhost.position = this.camera.position.add(dir.scale(this.grabbingStartDistance));
+
+ let y = 0;
+
+ for (const [id, o] of this.objects.entries().filter(([_id, o]) => o !== this.grabbing)) {
+ for (const om of o.getChildMeshes()) {
+ const omb = om.getBoundingInfo().boundingBox;
+ for (const tm of this.grabbing.getChildMeshes()) {
+ const tmb = tm.getBoundingInfo().boundingBox;
+ if (isIntersectXZ(tmb, omb)) {
+ const topY = omb.maximumWorld.y;
+ if (y === 0 || topY > y) {
+ y = topY;
+ }
+ }
+ }
+ }
+ }
+
+ this.grabbing.position = this.grabbingGhost.position.clone();
+ this.grabbing.position.y = y;
+ } else {
+ this.highlightedObjectId = null;
+ const ray = new BABYLON.Ray(this.camera.position, this.camera.getDirection(BABYLON.Axis.Z), 1000/*cm*/);
+ for (const [id, o] of this.objects.entries()) {
+ for (const om of o.getChildMeshes()) {
+ if (om.outlineColor.equals(new BABYLON.Color3(1, 0, 0))) {
+ om.outlineColor = new BABYLON.Color3(0, 0, 0);
+ }
+ }
+ }
+ const hit = this.scene.pickWithRay(ray)!;
+ if (hit.pickedMesh != null) {
+ const oid = hit.pickedMesh.metadata.objectId;
+ if (oid != null && this.objects.has(oid)) {
+ this.highlightedObjectId = oid;
+ const o = this.objects.get(oid)!;
+ for (const om of o.getChildMeshes()) {
+ om.outlineColor = new BABYLON.Color3(1, 0, 0);
+ }
+ }
+ }
+ }
+ }, 10));
+
+ this.engine.runRenderLoop(() => {
+ //const ray = new BABYLON.Ray(this.camera.position, this.camera.getDirection(BABYLON.Axis.Z), 1000/*cm*/);
+ //for (const mesh of this.scene.meshes) {
+ // if (mesh.outlineColor.equals(new BABYLON.Color3(1, 0, 0))) {
+ // mesh.outlineColor = new BABYLON.Color3(0, 0, 0);
+ // }
+ //}
+ //const hit = this.scene.pickWithRay(ray)!;
+ //if (hit.pickedMesh != null) {
+ // hit.pickedMesh.outlineColor = new BABYLON.Color3(1, 0, 0);
+ //}
+
+ //if (this.camera.position.x > (this.ROOM_SIZE / 2) - 2/*cm*/) {
+ // this.camera.position.x = (this.ROOM_SIZE / 2) - 2/*cm*/;
+ //} else if (this.camera.position.x < -(this.ROOM_SIZE / 2) + 2/*cm*/) {
+ // this.camera.position.x = -(this.ROOM_SIZE / 2) + 2/*cm*/;
+ //}
+ //if (this.camera.position.z > (this.ROOM_SIZE / 2) - 2/*cm*/) {
+ // this.camera.position.z = (this.ROOM_SIZE / 2) - 2/*cm*/;
+ //} else if (this.camera.position.z < -(this.ROOM_SIZE / 2) + 2/*cm*/) {
+ // this.camera.position.z = -(this.ROOM_SIZE / 2) + 2/*cm*/;
+ //}
+
+ this.scene.render();
+ });
+ }
+
+ private async loadRoomModel(type: RoomDef['roomType']) {
+ const roomObj = await BABYLON.ImportMeshAsync('/client-assets/room/rooms/default.glb', this.scene);
+ roomObj.meshes[0].scaling = new BABYLON.Vector3(-100, 100, 100);
+ roomObj.meshes[0].bakeCurrentTransformIntoVertices();
+ for (const mesh of roomObj.meshes) {
+ console.log(mesh.name);
+ mesh.isPickable = false;
+ mesh.checkCollisions = false;
+
+ //if (mesh.name === '__root__') continue;
+ if (mesh.name.startsWith('Window')) {
+ mesh.receiveShadows = false;
+ continue;
+ }
+ mesh.receiveShadows = true;
+ this.shadowGenerator1.addShadowCaster(mesh);
+ this.shadowGenerator2.addShadowCaster(mesh);
+ }
+ }
+
+ private async loadObject(id: string, type: RoomDef['objects'][number], position: BABYLON.Vector3, rotation: BABYLON.Vector3) {
+ const obj = await BABYLON.ImportMeshAsync(`/client-assets/room/objects/${type}/${type}.glb`, this.scene);
+ obj.meshes[0].scaling = new BABYLON.Vector3(-100, 100, 100);
+ obj.meshes[0].bakeCurrentTransformIntoVertices();
+ obj.meshes[0].position = position;
+ obj.meshes[0].rotation = rotation;
+
+ if (_DEV_) {
+ obj.meshes[0].showBoundingBox = true;
+ }
+
+ for (const mesh of obj.meshes) {
+ mesh.metadata = { isObject: true, objectId: id, objectType: type };
+ mesh.checkCollisions = true;
+ //if (mesh.name === '__root__') continue;
+ mesh.receiveShadows = true;
+ this.shadowGenerator1.addShadowCaster(mesh);
+ this.shadowGenerator2.addShadowCaster(mesh);
+
+ //if (mesh.material != null) {
+ // mesh.material.renderOutline = true;
+ // mesh.material.outlineWidth = 1;
+ // mesh.material.outlineColor = new BABYLON.Color3(0, 0, 0);
+ // mesh.material.outlineAlpha = 1.0;
+ //}
+
+ mesh.renderOutline = true;
+ mesh.outlineWidth = 0.003;
+ mesh.outlineColor = new BABYLON.Color3(0.2, 0.2, 0.2);
+ }
+
+ this.objects.set(id, obj.meshes[0]);
+
+ if (type === 'mug') {
+ const steamParticleSystem = new BABYLON.ParticleSystem('steamParticleSystem', 8, this.scene);
+ steamParticleSystem.particleTexture = new BABYLON.Texture('/client-assets/room/steam.png');
+ steamParticleSystem.emitter = position.add(new BABYLON.Vector3(0, 5/*cm*/, 0));
+ steamParticleSystem.minEmitBox = new BABYLON.Vector3(-1/*cm*/, 0, -1/*cm*/);
+ steamParticleSystem.maxEmitBox = new BABYLON.Vector3(1/*cm*/, 0, 1/*cm*/);
+ steamParticleSystem.minEmitPower = 10;
+ steamParticleSystem.maxEmitPower = 12;
+ steamParticleSystem.minLifeTime = 1;
+ steamParticleSystem.maxLifeTime = 3;
+ steamParticleSystem.minSize = 10/*cm*/;
+ steamParticleSystem.maxSize = 15/*cm*/;
+ steamParticleSystem.direction1 = new BABYLON.Vector3(-0.3, 1, 0.3);
+ steamParticleSystem.direction2 = new BABYLON.Vector3(0.3, 1, -0.3);
+ steamParticleSystem.emitRate = 0.5;
+ steamParticleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ADD;
+ steamParticleSystem.color1 = new BABYLON.Color4(1, 1, 1, 0.3);
+ steamParticleSystem.color2 = new BABYLON.Color4(1, 1, 1, 0.2);
+ steamParticleSystem.colorDead = new BABYLON.Color4(1, 1, 1, 0);
+ steamParticleSystem.start();
+ }
+ }
+
+ public grab() {
+ if (this.grabbing != null) {
+ this.grabbing = null;
+ this.grabbingStartDistance = null;
+ if (this.grabbingGhost != null) {
+ this.grabbingGhost.dispose(false, true);
+ this.grabbingGhost = null;
+ }
+ return;
+ }
+ if (this.highlightedObjectId == null) return;
+ const highlightedObject = this.objects.get(this.highlightedObjectId)!;
+ this.grabbing = highlightedObject;
+ this.grabbingStartDistance = BABYLON.Vector3.Distance(this.camera.position, highlightedObject.position);
+ this.grabbingGhost = highlightedObject.clone('ghost', null, false);
+ this.grabbingGhost!.getChildMeshes().forEach(m => {
+ m.metadata = {};
+ if (m.material) {
+ const mat = m.material.clone();
+ mat.alpha = 0.5;
+ m.material = mat;
+ }
+ });
+ }
+
+ public destroy() {
+ for (const id of this.intervalIds) {
+ window.clearInterval(id);
+ }
+ this.intervalIds = [];
+ this.engine.dispose();
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7369e95299..e499fcc108 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -653,6 +653,15 @@ importers:
'@analytics/google-analytics':
specifier: 1.1.0
version: 1.1.0
+ '@babylonjs/core':
+ specifier: 8.49.6
+ version: 8.49.6
+ '@babylonjs/loaders':
+ specifier: 8.49.6
+ version: 8.49.6(@babylonjs/core@8.49.6)(babylonjs-gltf2interface@8.49.6)
+ '@babylonjs/materials':
+ specifier: 8.49.6
+ version: 8.49.6(@babylonjs/core@8.49.6)
'@discordapp/twemoji':
specifier: 16.0.1
version: 16.0.1
@@ -1979,6 +1988,20 @@ packages:
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
+ '@babylonjs/core@8.49.6':
+ resolution: {integrity: sha512-Q0wsDfDQhwXhE22ltb89hL+XYaDzBLGDr/sSlKUEsHtALK+u36Ttwa8wVD0XJP30pgFpKIrd1LvdSB9FemNwzg==}
+
+ '@babylonjs/loaders@8.49.6':
+ resolution: {integrity: sha512-KsguPMqonctgvyjCcR8A3izGaoQoQrEdG3n4mZ4scX/WHskAciW5P/zsE3AUYugOAb+TL7iBW5VCb+sz/uEkVw==}
+ peerDependencies:
+ '@babylonjs/core': ^8.0.0
+ babylonjs-gltf2interface: ^8.0.0
+
+ '@babylonjs/materials@8.49.6':
+ resolution: {integrity: sha512-xDfgexV8y5Lp7Ftk8i+DWgERTSmwdLxUIOs5/9yTQTHdecdTZ0gNm5iGTWWdNvGCAX5wqd74Cg4Fwvjok1JeuQ==}
+ peerDependencies:
+ '@babylonjs/core': ^8.6.0
+
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
@@ -5439,6 +5462,9 @@ packages:
resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==}
engines: {node: '>= 10.0.0'}
+ babylonjs-gltf2interface@8.49.6:
+ resolution: {integrity: sha512-7qxi48GxEgX9SIZf1Eze+25YCUUY9X6ZIuoozg0rHZyY9gQBso7HUIWLznsQHeUXey19QS/zirrP1spm1PW8Vw==}
+
bail@2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
@@ -10831,6 +10857,9 @@ packages:
vue-component-type-helpers@3.2.2:
resolution: {integrity: sha512-x8C2nx5XlUNM0WirgfTkHjJGO/ABBxlANZDtHw2HclHtQnn+RFPTnbjMJn8jHZW4TlUam0asHcA14lf1C6Jb+A==}
+ vue-component-type-helpers@3.2.4:
+ resolution: {integrity: sha512-05lR16HeZDcDpB23ku5b5f1fBOoHqFnMiKRr2CiEvbG5Ux4Yi0McmQBOET0dR0nxDXosxyVqv67q6CzS3AK8rw==}
+
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
@@ -12261,6 +12290,17 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
+ '@babylonjs/core@8.49.6': {}
+
+ '@babylonjs/loaders@8.49.6(@babylonjs/core@8.49.6)(babylonjs-gltf2interface@8.49.6)':
+ dependencies:
+ '@babylonjs/core': 8.49.6
+ babylonjs-gltf2interface: 8.49.6
+
+ '@babylonjs/materials@8.49.6(@babylonjs/core@8.49.6)':
+ dependencies:
+ '@babylonjs/core': 8.49.6
+
'@bcoe/v8-coverage@0.2.3': {}
'@bcoe/v8-coverage@1.0.2': {}
@@ -14807,7 +14847,7 @@ snapshots:
storybook: 10.1.11(@testing-library/dom@10.4.0)(bufferutil@4.1.0)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(utf-8-validate@6.0.6)
type-fest: 2.19.0
vue: 3.5.26(typescript@5.9.3)
- vue-component-type-helpers: 3.2.2
+ vue-component-type-helpers: 3.2.4
'@stylistic/eslint-plugin@5.5.0(eslint@9.39.2)':
dependencies:
@@ -16308,6 +16348,8 @@ snapshots:
dependencies:
'@babel/types': 7.28.5
+ babylonjs-gltf2interface@8.49.6: {}
+
bail@2.0.2: {}
balanced-match@1.0.2: {}
@@ -22562,6 +22604,8 @@ snapshots:
vue-component-type-helpers@3.2.2: {}
+ vue-component-type-helpers@3.2.4: {}
+
vue-demi@0.14.10(vue@3.5.26(typescript@5.9.3)):
dependencies:
vue: 3.5.26(typescript@5.9.3)