diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2020-05-09 15:47:20 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2020-05-09 15:47:20 +0900 |
| commit | 0294061c00cc424c9840b65a4ad3dfe7cc30a2f0 (patch) | |
| tree | 3333be0afea50c7a24bb86b683589244c40f53d2 /src | |
| parent | refactor(client): Use getters to avoid watch vuex (diff) | |
| download | sharkey-0294061c00cc424c9840b65a4ad3dfe7cc30a2f0.tar.gz sharkey-0294061c00cc424c9840b65a4ad3dfe7cc30a2f0.tar.bz2 sharkey-0294061c00cc424c9840b65a4ad3dfe7cc30a2f0.zip | |
feat(client): Reimplement Misskey Rooms
Diffstat (limited to 'src')
147 files changed, 1605 insertions, 0 deletions
diff --git a/src/client/assets/room/furnitures/bed/bed.blend b/src/client/assets/room/furnitures/bed/bed.blend Binary files differnew file mode 100644 index 0000000000..731df76d0c --- /dev/null +++ b/src/client/assets/room/furnitures/bed/bed.blend diff --git a/src/client/assets/room/furnitures/bed/bed.glb b/src/client/assets/room/furnitures/bed/bed.glb Binary files differnew file mode 100644 index 0000000000..f35ecb9ef4 --- /dev/null +++ b/src/client/assets/room/furnitures/bed/bed.glb diff --git a/src/client/assets/room/furnitures/bin/bin.blend b/src/client/assets/room/furnitures/bin/bin.blend Binary files differnew file mode 100644 index 0000000000..8d459a0869 --- /dev/null +++ b/src/client/assets/room/furnitures/bin/bin.blend diff --git a/src/client/assets/room/furnitures/bin/bin.glb b/src/client/assets/room/furnitures/bin/bin.glb Binary files differnew file mode 100644 index 0000000000..b45f203802 --- /dev/null +++ b/src/client/assets/room/furnitures/bin/bin.glb diff --git a/src/client/assets/room/furnitures/book/book.blend b/src/client/assets/room/furnitures/book/book.blend Binary files differnew file mode 100644 index 0000000000..0d4899d4ae --- /dev/null +++ b/src/client/assets/room/furnitures/book/book.blend diff --git a/src/client/assets/room/furnitures/book/book.glb b/src/client/assets/room/furnitures/book/book.glb Binary files differnew file mode 100644 index 0000000000..546893da06 --- /dev/null +++ b/src/client/assets/room/furnitures/book/book.glb diff --git a/src/client/assets/room/furnitures/book2/barcode.png b/src/client/assets/room/furnitures/book2/barcode.png Binary files differnew file mode 100644 index 0000000000..37cfe5add3 --- /dev/null +++ b/src/client/assets/room/furnitures/book2/barcode.png diff --git a/src/client/assets/room/furnitures/book2/book2.blend b/src/client/assets/room/furnitures/book2/book2.blend Binary files differnew file mode 100644 index 0000000000..e0fdb48101 --- /dev/null +++ b/src/client/assets/room/furnitures/book2/book2.blend diff --git a/src/client/assets/room/furnitures/book2/book2.glb b/src/client/assets/room/furnitures/book2/book2.glb Binary files differnew file mode 100644 index 0000000000..2b26402f8c --- /dev/null +++ b/src/client/assets/room/furnitures/book2/book2.glb diff --git a/src/client/assets/room/furnitures/book2/texture.afdesign b/src/client/assets/room/furnitures/book2/texture.afdesign Binary files differnew file mode 100644 index 0000000000..b63771607a --- /dev/null +++ b/src/client/assets/room/furnitures/book2/texture.afdesign diff --git a/src/client/assets/room/furnitures/book2/texture.png b/src/client/assets/room/furnitures/book2/texture.png Binary files differnew file mode 100644 index 0000000000..5aa84f0340 --- /dev/null +++ b/src/client/assets/room/furnitures/book2/texture.png diff --git a/src/client/assets/room/furnitures/book2/uv.png b/src/client/assets/room/furnitures/book2/uv.png Binary files differnew file mode 100644 index 0000000000..61c4fb0400 --- /dev/null +++ b/src/client/assets/room/furnitures/book2/uv.png diff --git a/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend Binary files differnew file mode 100644 index 0000000000..3a528de32a --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend diff --git a/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb Binary files differnew file mode 100644 index 0000000000..bed372e94f --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb diff --git a/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend Binary files differnew file mode 100644 index 0000000000..5f146267ac --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend diff --git a/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb Binary files differnew file mode 100644 index 0000000000..85fcb5c0b6 --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb diff --git a/src/client/assets/room/furnitures/cardboard-box2/texture.png b/src/client/assets/room/furnitures/cardboard-box2/texture.png Binary files differnew file mode 100644 index 0000000000..e498d8f65b --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box2/texture.png diff --git a/src/client/assets/room/furnitures/cardboard-box2/uv.png b/src/client/assets/room/furnitures/cardboard-box2/uv.png Binary files differnew file mode 100644 index 0000000000..d547843ee0 --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box2/uv.png diff --git a/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend Binary files differnew file mode 100644 index 0000000000..00681a3cfd --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend diff --git a/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb Binary files differnew file mode 100644 index 0000000000..1ef0427689 --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb diff --git a/src/client/assets/room/furnitures/cardboard-box3/texture.png b/src/client/assets/room/furnitures/cardboard-box3/texture.png Binary files differnew file mode 100644 index 0000000000..56c914cb9d --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box3/texture.png diff --git a/src/client/assets/room/furnitures/cardboard-box3/texture.xcf b/src/client/assets/room/furnitures/cardboard-box3/texture.xcf Binary files differnew file mode 100644 index 0000000000..7ffb3e3439 --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box3/texture.xcf diff --git a/src/client/assets/room/furnitures/cardboard-box3/uv.png b/src/client/assets/room/furnitures/cardboard-box3/uv.png Binary files differnew file mode 100644 index 0000000000..797ac509db --- /dev/null +++ b/src/client/assets/room/furnitures/cardboard-box3/uv.png diff --git a/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend Binary files differnew file mode 100644 index 0000000000..750343d4f0 --- /dev/null +++ b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend diff --git a/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb Binary files differnew file mode 100644 index 0000000000..3066a69e35 --- /dev/null +++ b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb diff --git a/src/client/assets/room/furnitures/chair/chair.blend b/src/client/assets/room/furnitures/chair/chair.blend Binary files differnew file mode 100644 index 0000000000..79c29a8401 --- /dev/null +++ b/src/client/assets/room/furnitures/chair/chair.blend diff --git a/src/client/assets/room/furnitures/chair/chair.glb b/src/client/assets/room/furnitures/chair/chair.glb Binary files differnew file mode 100644 index 0000000000..08ee1a0bb0 --- /dev/null +++ b/src/client/assets/room/furnitures/chair/chair.glb diff --git a/src/client/assets/room/furnitures/chair2/chair2.blend b/src/client/assets/room/furnitures/chair2/chair2.blend Binary files differnew file mode 100644 index 0000000000..c6a1acd96f --- /dev/null +++ b/src/client/assets/room/furnitures/chair2/chair2.blend diff --git a/src/client/assets/room/furnitures/chair2/chair2.glb b/src/client/assets/room/furnitures/chair2/chair2.glb Binary files differnew file mode 100644 index 0000000000..5ea2f3518b --- /dev/null +++ b/src/client/assets/room/furnitures/chair2/chair2.glb diff --git a/src/client/assets/room/furnitures/color-box/color-box.blend b/src/client/assets/room/furnitures/color-box/color-box.blend Binary files differnew file mode 100644 index 0000000000..f96a4ff766 --- /dev/null +++ b/src/client/assets/room/furnitures/color-box/color-box.blend diff --git a/src/client/assets/room/furnitures/color-box/color-box.glb b/src/client/assets/room/furnitures/color-box/color-box.glb Binary files differnew file mode 100644 index 0000000000..43f2abcae8 --- /dev/null +++ b/src/client/assets/room/furnitures/color-box/color-box.glb diff --git a/src/client/assets/room/furnitures/corkboard/corkboard.blend b/src/client/assets/room/furnitures/corkboard/corkboard.blend Binary files differnew file mode 100644 index 0000000000..9a7e1878cd --- /dev/null +++ b/src/client/assets/room/furnitures/corkboard/corkboard.blend diff --git a/src/client/assets/room/furnitures/corkboard/corkboard.glb b/src/client/assets/room/furnitures/corkboard/corkboard.glb Binary files differnew file mode 100644 index 0000000000..fee108fb91 --- /dev/null +++ b/src/client/assets/room/furnitures/corkboard/corkboard.glb diff --git a/src/client/assets/room/furnitures/cube/cube.blend b/src/client/assets/room/furnitures/cube/cube.blend Binary files differnew file mode 100644 index 0000000000..1af5bf40a9 --- /dev/null +++ b/src/client/assets/room/furnitures/cube/cube.blend diff --git a/src/client/assets/room/furnitures/cube/cube.glb b/src/client/assets/room/furnitures/cube/cube.glb Binary files differnew file mode 100644 index 0000000000..4ac8b6036d --- /dev/null +++ b/src/client/assets/room/furnitures/cube/cube.glb diff --git a/src/client/assets/room/furnitures/cup-noodle/cup-noodle.blend b/src/client/assets/room/furnitures/cup-noodle/cup-noodle.blend Binary files differnew file mode 100644 index 0000000000..37ca8868c7 --- /dev/null +++ b/src/client/assets/room/furnitures/cup-noodle/cup-noodle.blend diff --git a/src/client/assets/room/furnitures/cup-noodle/cup-noodle.glb b/src/client/assets/room/furnitures/cup-noodle/cup-noodle.glb Binary files differnew file mode 100644 index 0000000000..58efb1b3b4 --- /dev/null +++ b/src/client/assets/room/furnitures/cup-noodle/cup-noodle.glb diff --git a/src/client/assets/room/furnitures/cup-noodle/noodle.png b/src/client/assets/room/furnitures/cup-noodle/noodle.png Binary files differnew file mode 100644 index 0000000000..1d74e0bbe7 --- /dev/null +++ b/src/client/assets/room/furnitures/cup-noodle/noodle.png diff --git a/src/client/assets/room/furnitures/desk/desk.blend b/src/client/assets/room/furnitures/desk/desk.blend Binary files differnew file mode 100644 index 0000000000..c88d01f0b2 --- /dev/null +++ b/src/client/assets/room/furnitures/desk/desk.blend diff --git a/src/client/assets/room/furnitures/desk/desk.glb b/src/client/assets/room/furnitures/desk/desk.glb Binary files differnew file mode 100644 index 0000000000..4a58513095 --- /dev/null +++ b/src/client/assets/room/furnitures/desk/desk.glb diff --git a/src/client/assets/room/furnitures/energy-drink/energy-drink.blend b/src/client/assets/room/furnitures/energy-drink/energy-drink.blend Binary files differnew file mode 100644 index 0000000000..65fc41273e --- /dev/null +++ b/src/client/assets/room/furnitures/energy-drink/energy-drink.blend diff --git a/src/client/assets/room/furnitures/energy-drink/energy-drink.glb b/src/client/assets/room/furnitures/energy-drink/energy-drink.glb Binary files differnew file mode 100644 index 0000000000..7fb1c27836 --- /dev/null +++ b/src/client/assets/room/furnitures/energy-drink/energy-drink.glb diff --git a/src/client/assets/room/furnitures/energy-drink/texture.afdesign b/src/client/assets/room/furnitures/energy-drink/texture.afdesign Binary files differnew file mode 100644 index 0000000000..8c117a49b1 --- /dev/null +++ b/src/client/assets/room/furnitures/energy-drink/texture.afdesign diff --git a/src/client/assets/room/furnitures/energy-drink/texture.png b/src/client/assets/room/furnitures/energy-drink/texture.png Binary files differnew file mode 100644 index 0000000000..484ca0f96f --- /dev/null +++ b/src/client/assets/room/furnitures/energy-drink/texture.png diff --git a/src/client/assets/room/furnitures/energy-drink/uv.png b/src/client/assets/room/furnitures/energy-drink/uv.png Binary files differnew file mode 100644 index 0000000000..2a3f20c999 --- /dev/null +++ b/src/client/assets/room/furnitures/energy-drink/uv.png diff --git a/src/client/assets/room/furnitures/eraser/cover.png b/src/client/assets/room/furnitures/eraser/cover.png Binary files differnew file mode 100644 index 0000000000..932a3fc62e --- /dev/null +++ b/src/client/assets/room/furnitures/eraser/cover.png diff --git a/src/client/assets/room/furnitures/eraser/cover.psd b/src/client/assets/room/furnitures/eraser/cover.psd Binary files differnew file mode 100644 index 0000000000..c393337833 --- /dev/null +++ b/src/client/assets/room/furnitures/eraser/cover.psd diff --git a/src/client/assets/room/furnitures/eraser/eraser-uv.png b/src/client/assets/room/furnitures/eraser/eraser-uv.png Binary files differnew file mode 100644 index 0000000000..89e4ea4c45 --- /dev/null +++ b/src/client/assets/room/furnitures/eraser/eraser-uv.png diff --git a/src/client/assets/room/furnitures/eraser/eraser.blend b/src/client/assets/room/furnitures/eraser/eraser.blend Binary files differnew file mode 100644 index 0000000000..103c54fbae --- /dev/null +++ b/src/client/assets/room/furnitures/eraser/eraser.blend diff --git a/src/client/assets/room/furnitures/eraser/eraser.glb b/src/client/assets/room/furnitures/eraser/eraser.glb Binary files differnew file mode 100644 index 0000000000..016b60df20 --- /dev/null +++ b/src/client/assets/room/furnitures/eraser/eraser.glb diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png b/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png Binary files differnew file mode 100644 index 0000000000..e3865ad15e --- /dev/null +++ b/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend Binary files differnew file mode 100644 index 0000000000..d59f87c1ee --- /dev/null +++ b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb Binary files differnew file mode 100644 index 0000000000..48b36ef347 --- /dev/null +++ b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png Binary files differnew file mode 100644 index 0000000000..7cee4b1859 --- /dev/null +++ b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd Binary files differnew file mode 100644 index 0000000000..cd59fc007b --- /dev/null +++ b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd diff --git a/src/client/assets/room/furnitures/fan/fan.blend b/src/client/assets/room/furnitures/fan/fan.blend Binary files differnew file mode 100644 index 0000000000..8c8106e5fe --- /dev/null +++ b/src/client/assets/room/furnitures/fan/fan.blend diff --git a/src/client/assets/room/furnitures/fan/fan.glb b/src/client/assets/room/furnitures/fan/fan.glb Binary files differnew file mode 100644 index 0000000000..d9367f3534 --- /dev/null +++ b/src/client/assets/room/furnitures/fan/fan.glb diff --git a/src/client/assets/room/furnitures/holo-display/holo-display.blend b/src/client/assets/room/furnitures/holo-display/holo-display.blend Binary files differnew file mode 100644 index 0000000000..56d2e1f819 --- /dev/null +++ b/src/client/assets/room/furnitures/holo-display/holo-display.blend diff --git a/src/client/assets/room/furnitures/holo-display/holo-display.glb b/src/client/assets/room/furnitures/holo-display/holo-display.glb Binary files differnew file mode 100644 index 0000000000..4d042a59b3 --- /dev/null +++ b/src/client/assets/room/furnitures/holo-display/holo-display.glb diff --git a/src/client/assets/room/furnitures/holo-display/ray-uv.png b/src/client/assets/room/furnitures/holo-display/ray-uv.png Binary files differnew file mode 100644 index 0000000000..aa7e817e0f --- /dev/null +++ b/src/client/assets/room/furnitures/holo-display/ray-uv.png diff --git a/src/client/assets/room/furnitures/holo-display/ray.png b/src/client/assets/room/furnitures/holo-display/ray.png Binary files differnew file mode 100644 index 0000000000..6a5d24e143 --- /dev/null +++ b/src/client/assets/room/furnitures/holo-display/ray.png diff --git a/src/client/assets/room/furnitures/keyboard/keyboard.blend b/src/client/assets/room/furnitures/keyboard/keyboard.blend Binary files differnew file mode 100644 index 0000000000..ab33d134b3 --- /dev/null +++ b/src/client/assets/room/furnitures/keyboard/keyboard.blend diff --git a/src/client/assets/room/furnitures/keyboard/keyboard.glb b/src/client/assets/room/furnitures/keyboard/keyboard.glb Binary files differnew file mode 100644 index 0000000000..15dc69f47a --- /dev/null +++ b/src/client/assets/room/furnitures/keyboard/keyboard.glb diff --git a/src/client/assets/room/furnitures/low-table/low-table.blend b/src/client/assets/room/furnitures/low-table/low-table.blend Binary files differnew file mode 100644 index 0000000000..e1592174d9 --- /dev/null +++ b/src/client/assets/room/furnitures/low-table/low-table.blend diff --git a/src/client/assets/room/furnitures/low-table/low-table.glb b/src/client/assets/room/furnitures/low-table/low-table.glb Binary files differnew file mode 100644 index 0000000000..c69bf35d7b --- /dev/null +++ b/src/client/assets/room/furnitures/low-table/low-table.glb diff --git a/src/client/assets/room/furnitures/mat/mat.blend b/src/client/assets/room/furnitures/mat/mat.blend Binary files differnew file mode 100644 index 0000000000..a1e1a68c55 --- /dev/null +++ b/src/client/assets/room/furnitures/mat/mat.blend diff --git a/src/client/assets/room/furnitures/mat/mat.glb b/src/client/assets/room/furnitures/mat/mat.glb Binary files differnew file mode 100644 index 0000000000..87ccd44e1a --- /dev/null +++ b/src/client/assets/room/furnitures/mat/mat.glb diff --git a/src/client/assets/room/furnitures/milk/milk-uv.png b/src/client/assets/room/furnitures/milk/milk-uv.png Binary files differnew file mode 100644 index 0000000000..258fd54638 --- /dev/null +++ b/src/client/assets/room/furnitures/milk/milk-uv.png diff --git a/src/client/assets/room/furnitures/milk/milk.blend b/src/client/assets/room/furnitures/milk/milk.blend Binary files differnew file mode 100644 index 0000000000..2df508d5b9 --- /dev/null +++ b/src/client/assets/room/furnitures/milk/milk.blend diff --git a/src/client/assets/room/furnitures/milk/milk.glb b/src/client/assets/room/furnitures/milk/milk.glb Binary files differnew file mode 100644 index 0000000000..b335fe3d02 --- /dev/null +++ b/src/client/assets/room/furnitures/milk/milk.glb diff --git a/src/client/assets/room/furnitures/milk/milk.png b/src/client/assets/room/furnitures/milk/milk.png Binary files differnew file mode 100644 index 0000000000..35181c8c8c --- /dev/null +++ b/src/client/assets/room/furnitures/milk/milk.png diff --git a/src/client/assets/room/furnitures/milk/milk.psd b/src/client/assets/room/furnitures/milk/milk.psd Binary files differnew file mode 100644 index 0000000000..f31e439277 --- /dev/null +++ b/src/client/assets/room/furnitures/milk/milk.psd diff --git a/src/client/assets/room/furnitures/monitor/monitor.blend b/src/client/assets/room/furnitures/monitor/monitor.blend Binary files differnew file mode 100644 index 0000000000..6c042ccdd8 --- /dev/null +++ b/src/client/assets/room/furnitures/monitor/monitor.blend diff --git a/src/client/assets/room/furnitures/monitor/monitor.glb b/src/client/assets/room/furnitures/monitor/monitor.glb Binary files differnew file mode 100644 index 0000000000..fc33286a15 --- /dev/null +++ b/src/client/assets/room/furnitures/monitor/monitor.glb diff --git a/src/client/assets/room/furnitures/monitor/monitor.psd b/src/client/assets/room/furnitures/monitor/monitor.psd Binary files differnew file mode 100644 index 0000000000..57afff9cd9 --- /dev/null +++ b/src/client/assets/room/furnitures/monitor/monitor.psd diff --git a/src/client/assets/room/furnitures/monitor/screen-uv.png b/src/client/assets/room/furnitures/monitor/screen-uv.png Binary files differnew file mode 100644 index 0000000000..35f74de8aa --- /dev/null +++ b/src/client/assets/room/furnitures/monitor/screen-uv.png diff --git a/src/client/assets/room/furnitures/monitor/screen.jpg b/src/client/assets/room/furnitures/monitor/screen.jpg Binary files differnew file mode 100644 index 0000000000..4004a1ede9 --- /dev/null +++ b/src/client/assets/room/furnitures/monitor/screen.jpg diff --git a/src/client/assets/room/furnitures/moon/moon.blend b/src/client/assets/room/furnitures/moon/moon.blend Binary files differnew file mode 100644 index 0000000000..4ff3deab8e --- /dev/null +++ b/src/client/assets/room/furnitures/moon/moon.blend diff --git a/src/client/assets/room/furnitures/moon/moon.glb b/src/client/assets/room/furnitures/moon/moon.glb Binary files differnew file mode 100644 index 0000000000..07fa7e4c02 --- /dev/null +++ b/src/client/assets/room/furnitures/moon/moon.glb diff --git a/src/client/assets/room/furnitures/moon/moon.jpg b/src/client/assets/room/furnitures/moon/moon.jpg Binary files differnew file mode 100644 index 0000000000..8988ac64b9 --- /dev/null +++ b/src/client/assets/room/furnitures/moon/moon.jpg diff --git a/src/client/assets/room/furnitures/mousepad/mousepad.blend b/src/client/assets/room/furnitures/mousepad/mousepad.blend Binary files differnew file mode 100644 index 0000000000..14bd139c94 --- /dev/null +++ b/src/client/assets/room/furnitures/mousepad/mousepad.blend diff --git a/src/client/assets/room/furnitures/mousepad/mousepad.glb b/src/client/assets/room/furnitures/mousepad/mousepad.glb Binary files differnew file mode 100644 index 0000000000..681ada49cd --- /dev/null +++ b/src/client/assets/room/furnitures/mousepad/mousepad.glb diff --git a/src/client/assets/room/furnitures/pc/motherboard-uv.png b/src/client/assets/room/furnitures/pc/motherboard-uv.png Binary files differnew file mode 100644 index 0000000000..355009fe7c --- /dev/null +++ b/src/client/assets/room/furnitures/pc/motherboard-uv.png diff --git a/src/client/assets/room/furnitures/pc/motherboard-uv.psd b/src/client/assets/room/furnitures/pc/motherboard-uv.psd Binary files differnew file mode 100644 index 0000000000..971f33f79e --- /dev/null +++ b/src/client/assets/room/furnitures/pc/motherboard-uv.psd diff --git a/src/client/assets/room/furnitures/pc/motherboard.jpg b/src/client/assets/room/furnitures/pc/motherboard.jpg Binary files differnew file mode 100644 index 0000000000..d894e4efcf --- /dev/null +++ b/src/client/assets/room/furnitures/pc/motherboard.jpg diff --git a/src/client/assets/room/furnitures/pc/pc.blend b/src/client/assets/room/furnitures/pc/pc.blend Binary files differnew file mode 100644 index 0000000000..13dfec6ccc --- /dev/null +++ b/src/client/assets/room/furnitures/pc/pc.blend diff --git a/src/client/assets/room/furnitures/pc/pc.glb b/src/client/assets/room/furnitures/pc/pc.glb Binary files differnew file mode 100644 index 0000000000..44a48b18ae --- /dev/null +++ b/src/client/assets/room/furnitures/pc/pc.glb diff --git a/src/client/assets/room/furnitures/pencil/pencil.blend b/src/client/assets/room/furnitures/pencil/pencil.blend Binary files differnew file mode 100644 index 0000000000..0fc6bdd776 --- /dev/null +++ b/src/client/assets/room/furnitures/pencil/pencil.blend diff --git a/src/client/assets/room/furnitures/pencil/pencil.glb b/src/client/assets/room/furnitures/pencil/pencil.glb Binary files differnew file mode 100644 index 0000000000..a938b5cdcc --- /dev/null +++ b/src/client/assets/room/furnitures/pencil/pencil.glb diff --git a/src/client/assets/room/furnitures/photoframe/photo-uv.png b/src/client/assets/room/furnitures/photoframe/photo-uv.png Binary files differnew file mode 100644 index 0000000000..9b94906413 --- /dev/null +++ b/src/client/assets/room/furnitures/photoframe/photo-uv.png diff --git a/src/client/assets/room/furnitures/photoframe/photo.jpg b/src/client/assets/room/furnitures/photoframe/photo.jpg Binary files differnew file mode 100644 index 0000000000..af14f0f36a --- /dev/null +++ b/src/client/assets/room/furnitures/photoframe/photo.jpg diff --git a/src/client/assets/room/furnitures/photoframe/photoframe.blend b/src/client/assets/room/furnitures/photoframe/photoframe.blend Binary files differnew file mode 100644 index 0000000000..4224cde45b --- /dev/null +++ b/src/client/assets/room/furnitures/photoframe/photoframe.blend diff --git a/src/client/assets/room/furnitures/photoframe/photoframe.glb b/src/client/assets/room/furnitures/photoframe/photoframe.glb Binary files differnew file mode 100644 index 0000000000..4255a77de6 --- /dev/null +++ b/src/client/assets/room/furnitures/photoframe/photoframe.glb diff --git a/src/client/assets/room/furnitures/piano/piano.blend b/src/client/assets/room/furnitures/piano/piano.blend Binary files differnew file mode 100644 index 0000000000..7653cdf672 --- /dev/null +++ b/src/client/assets/room/furnitures/piano/piano.blend diff --git a/src/client/assets/room/furnitures/piano/piano.glb b/src/client/assets/room/furnitures/piano/piano.glb Binary files differnew file mode 100644 index 0000000000..7242e78ceb --- /dev/null +++ b/src/client/assets/room/furnitures/piano/piano.glb diff --git a/src/client/assets/room/furnitures/pinguin/pinguin.blend b/src/client/assets/room/furnitures/pinguin/pinguin.blend Binary files differnew file mode 100644 index 0000000000..514c713e4c --- /dev/null +++ b/src/client/assets/room/furnitures/pinguin/pinguin.blend diff --git a/src/client/assets/room/furnitures/pinguin/pinguin.glb b/src/client/assets/room/furnitures/pinguin/pinguin.glb Binary files differnew file mode 100644 index 0000000000..6df34c06e9 --- /dev/null +++ b/src/client/assets/room/furnitures/pinguin/pinguin.glb diff --git a/src/client/assets/room/furnitures/plant/plant-soil-uv.png b/src/client/assets/room/furnitures/plant/plant-soil-uv.png Binary files differnew file mode 100644 index 0000000000..d4971a896c --- /dev/null +++ b/src/client/assets/room/furnitures/plant/plant-soil-uv.png diff --git a/src/client/assets/room/furnitures/plant/plant-soil.png b/src/client/assets/room/furnitures/plant/plant-soil.png Binary files differnew file mode 100644 index 0000000000..e79ccd240e --- /dev/null +++ b/src/client/assets/room/furnitures/plant/plant-soil.png diff --git a/src/client/assets/room/furnitures/plant/plant-soil.psd b/src/client/assets/room/furnitures/plant/plant-soil.psd Binary files differnew file mode 100644 index 0000000000..1457b7ea5b --- /dev/null +++ b/src/client/assets/room/furnitures/plant/plant-soil.psd diff --git a/src/client/assets/room/furnitures/plant/plant.blend b/src/client/assets/room/furnitures/plant/plant.blend Binary files differnew file mode 100644 index 0000000000..aa38c7b54e --- /dev/null +++ b/src/client/assets/room/furnitures/plant/plant.blend diff --git a/src/client/assets/room/furnitures/plant/plant.glb b/src/client/assets/room/furnitures/plant/plant.glb Binary files differnew file mode 100644 index 0000000000..38422b4a9b --- /dev/null +++ b/src/client/assets/room/furnitures/plant/plant.glb diff --git a/src/client/assets/room/furnitures/plant2/plant2.blend b/src/client/assets/room/furnitures/plant2/plant2.blend Binary files differnew file mode 100644 index 0000000000..6592c5d98d --- /dev/null +++ b/src/client/assets/room/furnitures/plant2/plant2.blend diff --git a/src/client/assets/room/furnitures/plant2/plant2.glb b/src/client/assets/room/furnitures/plant2/plant2.glb Binary files differnew file mode 100644 index 0000000000..223e6f5834 --- /dev/null +++ b/src/client/assets/room/furnitures/plant2/plant2.glb diff --git a/src/client/assets/room/furnitures/plant2/soil.png b/src/client/assets/room/furnitures/plant2/soil.png Binary files differnew file mode 100644 index 0000000000..e79ccd240e --- /dev/null +++ b/src/client/assets/room/furnitures/plant2/soil.png diff --git a/src/client/assets/room/furnitures/poster-h/poster-h.blend b/src/client/assets/room/furnitures/poster-h/poster-h.blend Binary files differnew file mode 100644 index 0000000000..40f944f3c1 --- /dev/null +++ b/src/client/assets/room/furnitures/poster-h/poster-h.blend diff --git a/src/client/assets/room/furnitures/poster-h/poster-h.glb b/src/client/assets/room/furnitures/poster-h/poster-h.glb Binary files differnew file mode 100644 index 0000000000..c6032c1009 --- /dev/null +++ b/src/client/assets/room/furnitures/poster-h/poster-h.glb diff --git a/src/client/assets/room/furnitures/poster-h/uv.png b/src/client/assets/room/furnitures/poster-h/uv.png Binary files differnew file mode 100644 index 0000000000..f854231e0b --- /dev/null +++ b/src/client/assets/room/furnitures/poster-h/uv.png diff --git a/src/client/assets/room/furnitures/poster-v/poster-v.blend b/src/client/assets/room/furnitures/poster-v/poster-v.blend Binary files differnew file mode 100644 index 0000000000..07fe971634 --- /dev/null +++ b/src/client/assets/room/furnitures/poster-v/poster-v.blend diff --git a/src/client/assets/room/furnitures/poster-v/poster-v.glb b/src/client/assets/room/furnitures/poster-v/poster-v.glb Binary files differnew file mode 100644 index 0000000000..6e3782f193 --- /dev/null +++ b/src/client/assets/room/furnitures/poster-v/poster-v.glb diff --git a/src/client/assets/room/furnitures/poster-v/uv.png b/src/client/assets/room/furnitures/poster-v/uv.png Binary files differnew file mode 100644 index 0000000000..7bb2bf809e --- /dev/null +++ b/src/client/assets/room/furnitures/poster-v/uv.png diff --git a/src/client/assets/room/furnitures/pudding/pudding.blend b/src/client/assets/room/furnitures/pudding/pudding.blend Binary files differnew file mode 100644 index 0000000000..bba40ce161 --- /dev/null +++ b/src/client/assets/room/furnitures/pudding/pudding.blend diff --git a/src/client/assets/room/furnitures/pudding/pudding.glb b/src/client/assets/room/furnitures/pudding/pudding.glb Binary files differnew file mode 100644 index 0000000000..06c9ed80cc --- /dev/null +++ b/src/client/assets/room/furnitures/pudding/pudding.glb diff --git a/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend Binary files differnew file mode 100644 index 0000000000..6c09067e78 --- /dev/null +++ b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend diff --git a/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb Binary files differnew file mode 100644 index 0000000000..d640df9b06 --- /dev/null +++ b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb diff --git a/src/client/assets/room/furnitures/server/rack-uv.png b/src/client/assets/room/furnitures/server/rack-uv.png Binary files differnew file mode 100644 index 0000000000..65bdb0ffd9 --- /dev/null +++ b/src/client/assets/room/furnitures/server/rack-uv.png diff --git a/src/client/assets/room/furnitures/server/rack.png b/src/client/assets/room/furnitures/server/rack.png Binary files differnew file mode 100644 index 0000000000..b851295cfa --- /dev/null +++ b/src/client/assets/room/furnitures/server/rack.png diff --git a/src/client/assets/room/furnitures/server/server.blend b/src/client/assets/room/furnitures/server/server.blend Binary files differnew file mode 100644 index 0000000000..6675dfbdc2 --- /dev/null +++ b/src/client/assets/room/furnitures/server/server.blend diff --git a/src/client/assets/room/furnitures/server/server.glb b/src/client/assets/room/furnitures/server/server.glb Binary files differnew file mode 100644 index 0000000000..a8b530a2d2 --- /dev/null +++ b/src/client/assets/room/furnitures/server/server.glb diff --git a/src/client/assets/room/furnitures/server/server.png b/src/client/assets/room/furnitures/server/server.png Binary files differnew file mode 100644 index 0000000000..8e9a0d716c --- /dev/null +++ b/src/client/assets/room/furnitures/server/server.png diff --git a/src/client/assets/room/furnitures/server/uv.png b/src/client/assets/room/furnitures/server/uv.png Binary files differnew file mode 100644 index 0000000000..ca2e747d16 --- /dev/null +++ b/src/client/assets/room/furnitures/server/uv.png diff --git a/src/client/assets/room/furnitures/sofa/sofa.blend b/src/client/assets/room/furnitures/sofa/sofa.blend Binary files differnew file mode 100644 index 0000000000..fb5aa51a2c --- /dev/null +++ b/src/client/assets/room/furnitures/sofa/sofa.blend diff --git a/src/client/assets/room/furnitures/sofa/sofa.glb b/src/client/assets/room/furnitures/sofa/sofa.glb Binary files differnew file mode 100644 index 0000000000..6ce77d94ac --- /dev/null +++ b/src/client/assets/room/furnitures/sofa/sofa.glb diff --git a/src/client/assets/room/furnitures/spiral/spiral.blend b/src/client/assets/room/furnitures/spiral/spiral.blend Binary files differnew file mode 100644 index 0000000000..9d3be77bce --- /dev/null +++ b/src/client/assets/room/furnitures/spiral/spiral.blend diff --git a/src/client/assets/room/furnitures/spiral/spiral.glb b/src/client/assets/room/furnitures/spiral/spiral.glb Binary files differnew file mode 100644 index 0000000000..ee8e3c23b1 --- /dev/null +++ b/src/client/assets/room/furnitures/spiral/spiral.glb diff --git a/src/client/assets/room/furnitures/tv/screen-uv.png b/src/client/assets/room/furnitures/tv/screen-uv.png Binary files differnew file mode 100644 index 0000000000..4bb74f031f --- /dev/null +++ b/src/client/assets/room/furnitures/tv/screen-uv.png diff --git a/src/client/assets/room/furnitures/tv/tv.blend b/src/client/assets/room/furnitures/tv/tv.blend Binary files differnew file mode 100644 index 0000000000..490e298e7b --- /dev/null +++ b/src/client/assets/room/furnitures/tv/tv.blend diff --git a/src/client/assets/room/furnitures/tv/tv.glb b/src/client/assets/room/furnitures/tv/tv.glb Binary files differnew file mode 100644 index 0000000000..b9bd23896b --- /dev/null +++ b/src/client/assets/room/furnitures/tv/tv.glb diff --git a/src/client/assets/room/furnitures/wall-clock/wall-clock.blend b/src/client/assets/room/furnitures/wall-clock/wall-clock.blend Binary files differnew file mode 100644 index 0000000000..0a61c8f01e --- /dev/null +++ b/src/client/assets/room/furnitures/wall-clock/wall-clock.blend diff --git a/src/client/assets/room/furnitures/wall-clock/wall-clock.glb b/src/client/assets/room/furnitures/wall-clock/wall-clock.glb Binary files differnew file mode 100644 index 0000000000..b9f0093a8d --- /dev/null +++ b/src/client/assets/room/furnitures/wall-clock/wall-clock.glb diff --git a/src/client/assets/room/rooms/default/default.blend b/src/client/assets/room/rooms/default/default.blend Binary files differnew file mode 100644 index 0000000000..661154724a --- /dev/null +++ b/src/client/assets/room/rooms/default/default.blend diff --git a/src/client/assets/room/rooms/default/default.glb b/src/client/assets/room/rooms/default/default.glb Binary files differnew file mode 100644 index 0000000000..3d378deee2 --- /dev/null +++ b/src/client/assets/room/rooms/default/default.glb diff --git a/src/client/assets/room/rooms/washitsu/husuma-uv.png b/src/client/assets/room/rooms/washitsu/husuma-uv.png Binary files differnew file mode 100644 index 0000000000..ae2fca3911 --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/husuma-uv.png diff --git a/src/client/assets/room/rooms/washitsu/husuma.png b/src/client/assets/room/rooms/washitsu/husuma.png Binary files differnew file mode 100644 index 0000000000..084cbed67c --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/husuma.png diff --git a/src/client/assets/room/rooms/washitsu/tatami-single1600.png b/src/client/assets/room/rooms/washitsu/tatami-single1600.png Binary files differnew file mode 100644 index 0000000000..c0e684d743 --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/tatami-single1600.png diff --git a/src/client/assets/room/rooms/washitsu/tatami-uv.png b/src/client/assets/room/rooms/washitsu/tatami-uv.png Binary files differnew file mode 100644 index 0000000000..5b16c66091 --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/tatami-uv.png diff --git a/src/client/assets/room/rooms/washitsu/tatami.afdesign b/src/client/assets/room/rooms/washitsu/tatami.afdesign Binary files differnew file mode 100644 index 0000000000..9300a26950 --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/tatami.afdesign diff --git a/src/client/assets/room/rooms/washitsu/tatami.png b/src/client/assets/room/rooms/washitsu/tatami.png Binary files differnew file mode 100644 index 0000000000..8894d040ae --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/tatami.png diff --git a/src/client/assets/room/rooms/washitsu/washitsu.blend b/src/client/assets/room/rooms/washitsu/washitsu.blend Binary files differnew file mode 100644 index 0000000000..84dc11374d --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/washitsu.blend diff --git a/src/client/assets/room/rooms/washitsu/washitsu.glb b/src/client/assets/room/rooms/washitsu/washitsu.glb Binary files differnew file mode 100644 index 0000000000..5b4767bc73 --- /dev/null +++ b/src/client/assets/room/rooms/washitsu/washitsu.glb diff --git a/src/client/pages/room/preview.vue b/src/client/pages/room/preview.vue new file mode 100644 index 0000000000..22228cf8cb --- /dev/null +++ b/src/client/pages/room/preview.vue @@ -0,0 +1,106 @@ +<template> +<canvas width="224" height="128"></canvas> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import * as THREE from 'three'; + +export default Vue.extend({ + data() { + return { + selected: null, + objectHeight: 0, + orbitRadius: 5 + }; + }, + + mounted() { + const canvas = this.$el; + + const width = canvas.width; + const height = canvas.height; + + const scene = new THREE.Scene(); + + const renderer = new THREE.WebGLRenderer({ + canvas: canvas, + antialias: true, + alpha: false + }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(width, height); + renderer.setClearColor(0x000000); + renderer.autoClear = false; + renderer.shadowMap.enabled = true; + renderer.shadowMap.cullFace = THREE.CullFaceBack; + + const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100); + camera.zoom = 10; + camera.position.x = 0; + camera.position.y = 2; + camera.position.z = 0; + camera.updateProjectionMatrix(); + scene.add(camera); + + const ambientLight = new THREE.AmbientLight(0xffffff, 1); + ambientLight.castShadow = false; + scene.add(ambientLight); + + const light = new THREE.PointLight(0xffffff, 1, 100); + light.position.set(3, 3, 3); + scene.add(light); + + const grid = new THREE.GridHelper(5, 16, 0x444444, 0x222222); + scene.add(grid); + + const render = () => { + const timer = Date.now() * 0.0004; + requestAnimationFrame(render); + + camera.position.y = Math.sin(Math.PI / 6) * this.orbitRadius; // Math.PI / 6 => 30deg + camera.position.z = Math.cos(timer) * this.orbitRadius; + camera.position.x = Math.sin(timer) * this.orbitRadius; + camera.lookAt(new THREE.Vector3(0, this.objectHeight / 2, 0)); + renderer.render(scene, camera); + }; + + this.selected = selected => { + const obj = selected.clone(); + + // Remove current object + const current = scene.getObjectByName('obj'); + if (current != null) { + scene.remove(current); + } + + // Add new object + obj.name = 'obj'; + obj.position.x = 0; + obj.position.y = 0; + obj.position.z = 0; + obj.rotation.x = 0; + obj.rotation.y = 0; + obj.rotation.z = 0; + obj.traverse(child => { + if (child instanceof THREE.Mesh) { + child.material = child.material.clone(); + return child.material.emissive.setHex(0x000000); + } + }); + const objectBoundingBox = new THREE.Box3().setFromObject(obj); + this.objectHeight = objectBoundingBox.max.y - objectBoundingBox.min.y; + + const objectWidth = objectBoundingBox.max.x - objectBoundingBox.min.x; + const objectDepth = objectBoundingBox.max.z - objectBoundingBox.min.z; + + const horizontal = Math.hypot(objectWidth, objectDepth) / camera.aspect; + this.orbitRadius = Math.max(horizontal, this.objectHeight) * camera.zoom * 0.625 / Math.tan(camera.fov * 0.5 * (Math.PI / 180)); + + scene.add(obj); + }; + + render(); + }, +}); +</script> diff --git a/src/client/pages/room/room.vue b/src/client/pages/room/room.vue new file mode 100644 index 0000000000..2dd221ddf1 --- /dev/null +++ b/src/client/pages/room/room.vue @@ -0,0 +1,296 @@ +<template> +<div class="hveuntkp"> + <portal to="avatar" v-if="user"><mk-avatar class="avatar" :user="user" :disable-preview="true"/></portal> + <portal to="title" v-if="user"> + <mfm + :text="$t('_rooms.roomOf', { user: user.name || user.username })" + :plain="true" :nowrap="true" :custom-emojis="user.emojis" :is-note="false" + /> + </portal> + + <div class="controller _card" v-if="objectSelected"> + <div class="_content"> + <p class="name">{{ selectedFurnitureName }}</p> + <x-preview ref="preview"/> + <template v-if="selectedFurnitureInfo.props"> + <div v-for="k in Object.keys(selectedFurnitureInfo.props)" :key="k"> + <p>{{ k }}</p> + <template v-if="selectedFurnitureInfo.props[k] === 'image'"> + <mk-button @click="chooseImage(k)">{{ $t('_rooms.chooseImage') }}</mk-button> + </template> + <template v-else-if="selectedFurnitureInfo.props[k] === 'color'"> + <input type="color" :value="selectedFurnitureProps ? selectedFurnitureProps[k] : null" @change="updateColor(k, $event)"/> + </template> + </div> + </template> + </div> + <div class="_content"> + <mk-button inline @click="translate()" :primary="isTranslateMode"><fa :icon="faArrowsAlt"/> {{ $t('_rooms.translate') }}</mk-button> + <mk-button inline @click="rotate()" :primary="isRotateMode"><fa :icon="faUndo"/> {{ $t('_rooms.rotate') }}</mk-button> + <mk-button inline v-if="isTranslateMode || isRotateMode" @click="exit()"><fa :icon="faBan"/> {{ $t('_rooms.exit') }}</mk-button> + </div> + <div class="_content"> + <mk-button @click="remove()"><fa :icon="faTrashAlt"/> {{ $t('_rooms.remove') }}</mk-button> + </div> + </div> + + <div class="menu _card" v-if="isMyRoom"> + <div class="_content"> + <mk-button @click="add()"><fa :icon="faBoxOpen"/> {{ $t('_rooms.addFurniture') }}</mk-button> + </div> + <div class="_content"> + <mk-select :value="roomType" @input="updateRoomType($event)"> + <template #label>{{ $t('_rooms.roomType') }}</template> + <option value="default">{{ $t('_rooms._roomType.default') }}</option> + <option value="washitsu">{{ $t('_rooms._roomType.washitsu') }}</option> + </mk-select> + <label v-if="roomType === 'default'"> + <span>{{ $t('_rooms.carpetColor') }}</span> + <input type="color" :value="carpetColor" @change="updateCarpetColor($event)"/> + </label> + </div> + <div class="_content"> + <mk-button inline :disabled="!changed" primary @click="save()"><fa :icon="faSave"/> {{ $t('save') }}</mk-button> + <mk-button inline @click="clear()"><fa :icon="faBroom"/> {{ $t('_rooms.clear') }}</mk-button> + </div> + </div> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import i18n from '../../i18n'; +import { Room } from '../../scripts/room/room'; +import parseAcct from '../../../misc/acct/parse'; +import XPreview from './preview.vue'; +const storeItems = require('../../scripts/room/furnitures.json5'); +import { faBoxOpen, faUndo, faArrowsAlt, faBan, faBroom } from '@fortawesome/free-solid-svg-icons'; +import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons'; +import { query as urlQuery } from '../../../prelude/url'; +import MkButton from '../../components/ui/button.vue'; +import MkSelect from '../../components/ui/select.vue'; + +let room: Room; + +export default Vue.extend({ + i18n, + + components: { + XPreview, + MkButton, + MkSelect, + }, + + props: { + acct: { + type: String, + required: true + }, + }, + + data() { + return { + user: null, + objectSelected: false, + selectedFurnitureName: null, + selectedFurnitureInfo: null, + selectedFurnitureProps: null, + roomType: null, + carpetColor: null, + isTranslateMode: false, + isRotateMode: false, + isMyRoom: false, + changed: false, + faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan, faBroom, + }; + }, + + async mounted() { + window.addEventListener('beforeunload', this.beforeunload); + + this.user = await this.$root.api('users/show', { + ...parseAcct(this.acct) + }); + + this.isMyRoom = this.$store.getters.isSignedIn && (this.$store.state.i.id === this.user.id); + + const roomInfo = await this.$root.api('room/show', { + userId: this.user.id + }); + + this.roomType = roomInfo.roomType; + this.carpetColor = roomInfo.carpetColor; + + room = new Room(this.user, this.isMyRoom, roomInfo, this.$el, { + graphicsQuality: this.$store.state.device.roomGraphicsQuality, + onChangeSelect: obj => { + this.objectSelected = obj != null; + if (obj) { + const f = room.findFurnitureById(obj.name); + this.selectedFurnitureName = this.$t('_rooms._furnitures.' + f.type); + this.selectedFurnitureInfo = storeItems.find(x => x.id === f.type); + this.selectedFurnitureProps = f.props + ? JSON.parse(JSON.stringify(f.props)) // Disable reactivity + : null; + this.$nextTick(() => { + this.$refs.preview.selected(obj); + }); + } + }, + useOrthographicCamera: this.$store.state.device.roomUseOrthographicCamera + }); + }, + + beforeRouteLeave(to, from, next) { + if (this.changed) { + this.$root.dialog({ + type: 'warning', + text: this.$t('leave-confirm'), + showCancelButton: true + }).then(({ canceled }) => { + if (canceled) { + next(false); + } else { + next(); + } + }); + } else { + next(); + } + }, + + beforeDestroy() { + room.destroy(); + window.removeEventListener('beforeunload', this.beforeunload); + }, + + methods: { + beforeunload(e: BeforeUnloadEvent) { + if (this.changed) { + e.preventDefault(); + e.returnValue = ''; + } + }, + + async add() { + const { canceled, result: id } = await this.$root.dialog({ + type: null, + title: this.$t('_rooms.addFurniture'), + select: { + items: storeItems.map(item => ({ + value: item.id, text: this.$t('_rooms._furnitures.' + item.id) + })) + }, + showCancelButton: true + }); + if (canceled) return; + room.addFurniture(id); + this.changed = true; + }, + + remove() { + this.isTranslateMode = false; + this.isRotateMode = false; + room.removeFurniture(); + this.changed = true; + }, + + save() { + this.$root.api('room/update', { + room: room.getRoomInfo() + }).then(() => { + this.changed = false; + this.$root.dialog({ + type: 'success', + iconOnly: true, autoClose: true + }); + }).catch((e: any) => { + this.$root.dialog({ + type: 'error', + text: e.message + }); + }); + }, + + clear() { + this.$root.dialog({ + type: 'warning', + text: this.$t('_rooms.clearConfirm'), + showCancelButton: true + }).then(({ canceled }) => { + if (canceled) return; + room.removeAllFurnitures(); + this.changed = true; + }); + }, + + chooseImage(key) { + this.$chooseDriveFile({ + multiple: false + }).then(file => { + room.updateProp(key, `/proxy/?${urlQuery({ url: file.thumbnailUrl })}`); + this.$refs.preview.selected(room.getSelectedObject()); + this.changed = true; + }); + }, + + updateColor(key, ev) { + room.updateProp(key, ev.target.value); + this.$refs.preview.selected(room.getSelectedObject()); + this.changed = true; + }, + + updateCarpetColor(ev) { + room.updateCarpetColor(ev.target.value); + this.carpetColor = ev.target.value; + this.changed = true; + }, + + updateRoomType(type) { + room.changeRoomType(type); + this.roomType = type; + this.changed = true; + }, + + translate() { + if (this.isTranslateMode) { + this.exit(); + } else { + this.isRotateMode = false; + this.isTranslateMode = true; + room.enterTransformMode('translate'); + } + this.changed = true; + }, + + rotate() { + if (this.isRotateMode) { + this.exit(); + } else { + this.isTranslateMode = false; + this.isRotateMode = true; + room.enterTransformMode('rotate'); + } + this.changed = true; + }, + + exit() { + this.isTranslateMode = false; + this.isRotateMode = false; + room.exitTransformMode(); + this.changed = true; + } + } +}); +</script> + +<style lang="scss" scoped> +.hveuntkp { + position: relative; + min-height: 500px; + + > ::v-deep canvas { + display: block; + } +} +</style> diff --git a/src/client/router.ts b/src/client/router.ts index d826d6b493..e997d2db99 100644 --- a/src/client/router.ts +++ b/src/client/router.ts @@ -18,6 +18,7 @@ export const router = new VueRouter({ ]}, { path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) }, { path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, + { path: '/@:acct/room', props: true, component: page('room/room') }, { path: '/announcements', component: page('announcements') }, { path: '/about', component: page('about') }, { path: '/about-misskey', component: page('about-misskey') }, diff --git a/src/client/scripts/room/furniture.ts b/src/client/scripts/room/furniture.ts new file mode 100644 index 0000000000..7734e32668 --- /dev/null +++ b/src/client/scripts/room/furniture.ts @@ -0,0 +1,21 @@ +export type RoomInfo = { + roomType: string; + carpetColor: string; + furnitures: Furniture[]; +}; + +export type Furniture = { + id: string; // 同じ家具が複数ある場合にそれぞれを識別するためのIDであり、家具IDではない + type: string; // こっちが家具ID(chairとか) + position: { + x: number; + y: number; + z: number; + }; + rotation: { + x: number; + y: number; + z: number; + }; + props?: Record<string, any>; +}; diff --git a/src/client/scripts/room/furnitures.json5 b/src/client/scripts/room/furnitures.json5 new file mode 100644 index 0000000000..7c1a90a3f9 --- /dev/null +++ b/src/client/scripts/room/furnitures.json5 @@ -0,0 +1,397 @@ +// 家具メタデータ + +// 家具にはユーザーが設定できるプロパティを設定可能です: +// +// props: { +// <propname>: <proptype> +// } +// +// proptype一覧: +// * image ... 画像選択ダイアログを出し、その画像のURLが格納されます +// * color ... 色選択コントロールを出し、選択された色が格納されます + +// 家具にカスタムテクスチャを適用できるようにするには、textureプロパティに以下の追加の情報を含めます: +// 便宜上そのUVのどの部分にカスタムテクスチャを貼り合わせるかのエリアをテクスチャエリアと呼びます。 +// UVは1024*1024だと仮定します。 +// +// <key>: { +// prop: <プロパティ名>, +// uv: { +// x: <テクスチャエリアX座標>, +// y: <テクスチャエリアY座標>, +// width: <テクスチャエリアの幅>, +// height: <テクスチャエリアの高さ>, +// }, +// } +// +// <key>には、カスタムテクスチャを適用したいメッシュ名を指定します +// <プロパティ名>には、カスタムテクスチャとして使用する画像を格納するプロパティ(前述)名を指定します + +// 家具にカスタムカラーを適用できるようにするには、colorプロパティに以下の追加の情報を含めます: +// +// <key>: <プロパティ名> +// +// <key>には、カスタムカラーを適用したいマテリアル名を指定します +// <プロパティ名>には、カスタムカラーとして使用する色を格納するプロパティ(前述)名を指定します + +[ + { + id: "milk", + place: "floor" + }, + { + id: "bed", + place: "floor" + }, + { + id: "low-table", + place: "floor", + props: { + color: 'color' + }, + color: { + Table: 'color' + } + }, + { + id: "desk", + place: "floor", + props: { + color: 'color' + }, + color: { + Board: 'color' + } + }, + { + id: "chair", + place: "floor", + props: { + color: 'color' + }, + color: { + Chair: 'color' + } + }, + { + id: "chair2", + place: "floor", + props: { + color1: 'color', + color2: 'color' + }, + color: { + Cushion: 'color1', + Leg: 'color2' + } + }, + { + id: "fan", + place: "wall" + }, + { + id: "pc", + place: "floor" + }, + { + id: "plant", + place: "floor" + }, + { + id: "plant2", + place: "floor" + }, + { + id: "eraser", + place: "floor" + }, + { + id: "pencil", + place: "floor" + }, + { + id: "pudding", + place: "floor" + }, + { + id: "cardboard-box", + place: "floor" + }, + { + id: "cardboard-box2", + place: "floor" + }, + { + id: "cardboard-box3", + place: "floor" + }, + { + id: "book", + place: "floor", + props: { + color: 'color' + }, + color: { + Cover: 'color' + } + }, + { + id: "book2", + place: "floor" + }, + { + id: "piano", + place: "floor" + }, + { + id: "facial-tissue", + place: "floor" + }, + { + id: "server", + place: "floor" + }, + { + id: "moon", + place: "floor" + }, + { + id: "corkboard", + place: "wall" + }, + { + id: "mousepad", + place: "floor", + props: { + color: 'color' + }, + color: { + Pad: 'color' + } + }, + { + id: "monitor", + place: "floor", + props: { + screen: 'image' + }, + texture: { + Screen: { + prop: 'screen', + uv: { + x: 0, + y: 434, + width: 1024, + height: 588, + }, + }, + }, + }, + { + id: "tv", + place: "floor", + props: { + screen: 'image' + }, + texture: { + Screen: { + prop: 'screen', + uv: { + x: 0, + y: 434, + width: 1024, + height: 588, + }, + }, + }, + }, + { + id: "keyboard", + place: "floor" + }, + { + id: "carpet-stripe", + place: "floor", + props: { + color1: 'color', + color2: 'color' + }, + color: { + CarpetAreaA: 'color1', + CarpetAreaB: 'color2' + }, + }, + { + id: "mat", + place: "floor", + props: { + color: 'color' + }, + color: { + Mat: 'color' + } + }, + { + id: "color-box", + place: "floor", + props: { + color: 'color' + }, + color: { + main: 'color' + } + }, + { + id: "wall-clock", + place: "wall" + }, + { + id: "cube", + place: "floor", + props: { + color: 'color' + }, + color: { + Cube: 'color' + } + }, + { + id: "photoframe", + place: "wall", + props: { + photo: 'image', + color: 'color' + }, + texture: { + Photo: { + prop: 'photo', + uv: { + x: 0, + y: 342, + width: 1024, + height: 683, + }, + }, + }, + color: { + Frame: 'color' + } + }, + { + id: "pinguin", + place: "floor", + props: { + body: 'color', + belly: 'color' + }, + color: { + Body: 'body', + Belly: 'belly', + } + }, + { + id: "rubik-cube", + place: "floor", + }, + { + id: "poster-h", + place: "wall", + props: { + picture: 'image' + }, + texture: { + Poster: { + prop: 'picture', + uv: { + x: 0, + y: 277, + width: 1024, + height: 745, + }, + }, + }, + }, + { + id: "poster-v", + place: "wall", + props: { + picture: 'image' + }, + texture: { + Poster: { + prop: 'picture', + uv: { + x: 0, + y: 0, + width: 745, + height: 1024, + }, + }, + }, + }, + { + id: "sofa", + place: "floor", + props: { + color: 'color' + }, + color: { + Sofa: 'color' + } + }, + { + id: "spiral", + place: "floor", + props: { + color: 'color' + }, + color: { + Step: 'color' + } + }, + { + id: "bin", + place: "floor", + props: { + color: 'color' + }, + color: { + Bin: 'color' + } + }, + { + id: "cup-noodle", + place: "floor" + }, + { + id: "holo-display", + place: "floor", + props: { + image: 'image' + }, + texture: { + Image_Front: { + prop: 'image', + uv: { + x: 0, + y: 0, + width: 1024, + height: 1024, + }, + }, + Image_Back: { + prop: 'image', + uv: { + x: 0, + y: 0, + width: 1024, + height: 1024, + }, + }, + }, + }, + { + id: 'energy-drink', + place: "floor", + } +] diff --git a/src/client/scripts/room/room.ts b/src/client/scripts/room/room.ts new file mode 100644 index 0000000000..a45fb11e4a --- /dev/null +++ b/src/client/scripts/room/room.ts @@ -0,0 +1,776 @@ +import autobind from 'autobind-decorator'; +import { v4 as uuid } from 'uuid'; +import * as THREE from 'three'; +import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; +import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js'; +import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; +import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; +import { Furniture, RoomInfo } from './furniture'; +import { query as urlQuery } from '../../../prelude/url'; +const furnitureDefs = require('./furnitures.json5'); + +THREE.ImageUtils.crossOrigin = ''; + +type Options = { + graphicsQuality: Room['graphicsQuality']; + onChangeSelect: Room['onChangeSelect']; + useOrthographicCamera: boolean; +}; + +/** + * MisskeyRoom Core Engine + */ +export class Room { + private clock: THREE.Clock; + private scene: THREE.Scene; + private renderer: THREE.WebGLRenderer; + private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera; + private controls: OrbitControls; + private composer: EffectComposer; + private mixers: THREE.AnimationMixer[] = []; + private furnitureControl: TransformControls; + private roomInfo: RoomInfo; + private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra'; + private roomObj: THREE.Object3D; + private objects: THREE.Object3D[] = []; + private selectedObject: THREE.Object3D = null; + private onChangeSelect: Function; + private isTransformMode = false; + private renderFrameRequestId: number; + + private get canvas(): HTMLCanvasElement { + return this.renderer.domElement; + } + + private get furnitures(): Furniture[] { + return this.roomInfo.furnitures; + } + + private set furnitures(furnitures: Furniture[]) { + this.roomInfo.furnitures = furnitures; + } + + private get enableShadow() { + return this.graphicsQuality != 'cheep'; + } + + private get usePostFXs() { + return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low'; + } + + private get shadowQuality() { + return ( + this.graphicsQuality === 'ultra' ? 16384 : + this.graphicsQuality === 'high' ? 8192 : + this.graphicsQuality === 'medium' ? 4096 : + this.graphicsQuality === 'low' ? 1024 : + 0); // cheep + } + + constructor(user, isMyRoom, roomInfo: RoomInfo, container: Element, options: Options) { + this.roomInfo = roomInfo; + this.graphicsQuality = options.graphicsQuality; + this.onChangeSelect = options.onChangeSelect; + + this.clock = new THREE.Clock(true); + + //#region Init a scene + this.scene = new THREE.Scene(); + + const width = container.clientWidth; + const height = container.clientHeight; + + //#region Init a renderer + this.renderer = new THREE.WebGLRenderer({ + antialias: false, + stencil: false, + alpha: false, + powerPreference: + this.graphicsQuality === 'ultra' ? 'high-performance' : + this.graphicsQuality === 'high' ? 'high-performance' : + this.graphicsQuality === 'medium' ? 'default' : + this.graphicsQuality === 'low' ? 'low-power' : + 'low-power' // cheep + }); + + this.renderer.setPixelRatio(window.devicePixelRatio); + this.renderer.setSize(width, height); + this.renderer.autoClear = false; + this.renderer.setClearColor(new THREE.Color(0x051f2d)); + this.renderer.shadowMap.enabled = this.enableShadow; + this.renderer.gammaOutput = true; + this.renderer.shadowMap.type = + this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'medium' ? THREE.PCFShadowMap : + this.graphicsQuality === 'low' ? THREE.BasicShadowMap : + THREE.BasicShadowMap; // cheep + + container.insertBefore(this.canvas, container.firstChild); + //#endregion + + //#region Init a camera + this.camera = options.useOrthographicCamera + ? new THREE.OrthographicCamera( + width / - 2, width / 2, height / 2, height / - 2, -10, 10) + : new THREE.PerspectiveCamera(45, width / height); + + if (options.useOrthographicCamera) { + this.camera.position.x = 2; + this.camera.position.y = 2; + this.camera.position.z = 2; + this.camera.zoom = 100; + this.camera.updateProjectionMatrix(); + } else { + this.camera.position.x = 5; + this.camera.position.y = 2; + this.camera.position.z = 5; + } + + this.scene.add(this.camera); + //#endregion + + //#region AmbientLight + const ambientLight = new THREE.AmbientLight(0xffffff, 1); + this.scene.add(ambientLight); + //#endregion + + if (this.graphicsQuality !== 'cheep') { + //#region Room light + const roomLight = new THREE.SpotLight(0xffffff, 0.1); + + roomLight.position.set(0, 8, 0); + roomLight.castShadow = this.enableShadow; + roomLight.shadow.bias = -0.0001; + roomLight.shadow.mapSize.width = this.shadowQuality; + roomLight.shadow.mapSize.height = this.shadowQuality; + roomLight.shadow.camera.near = 0.1; + roomLight.shadow.camera.far = 9; + roomLight.shadow.camera.fov = 45; + + this.scene.add(roomLight); + //#endregion + } + + //#region Out light + const outLight1 = new THREE.SpotLight(0xffffff, 0.4); + outLight1.position.set(9, 3, -2); + outLight1.castShadow = this.enableShadow; + outLight1.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある + outLight1.shadow.mapSize.width = this.shadowQuality; + outLight1.shadow.mapSize.height = this.shadowQuality; + outLight1.shadow.camera.near = 6; + outLight1.shadow.camera.far = 15; + outLight1.shadow.camera.fov = 45; + this.scene.add(outLight1); + + const outLight2 = new THREE.SpotLight(0xffffff, 0.2); + outLight2.position.set(-2, 3, 9); + outLight2.castShadow = false; + outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある + outLight2.shadow.camera.near = 6; + outLight2.shadow.camera.far = 15; + outLight2.shadow.camera.fov = 45; + this.scene.add(outLight2); + //#endregion + + //#region Init a controller + this.controls = new OrbitControls(this.camera, this.canvas); + + this.controls.target.set(0, 1, 0); + this.controls.enableZoom = true; + this.controls.enablePan = isMyRoom; + this.controls.minPolarAngle = 0; + this.controls.maxPolarAngle = Math.PI / 2; + this.controls.minAzimuthAngle = 0; + this.controls.maxAzimuthAngle = Math.PI / 2; + this.controls.enableDamping = true; + this.controls.dampingFactor = 0.2; + //#endregion + + //#region POST FXs + if (!this.usePostFXs) { + this.composer = null; + } else { + const renderTarget = new THREE.WebGLRenderTarget(width, height, { + minFilter: THREE.LinearFilter, + magFilter: THREE.LinearFilter, + format: THREE.RGBFormat, + stencilBuffer: false, + }); + + const fxaa = new ShaderPass(FXAAShader); + fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height); + fxaa.renderToScreen = true; + + this.composer = new EffectComposer(this.renderer, renderTarget); + this.composer.addPass(new RenderPass(this.scene, this.camera)); + if (this.graphicsQuality === 'ultra') { + this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512)); + } + this.composer.addPass(fxaa); + } + //#endregion + //#endregion + + //#region Label + //#region Avatar + const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`; + + const textureLoader = new THREE.TextureLoader(); + textureLoader.crossOrigin = 'anonymous'; + + const iconTexture = textureLoader.load(avatarUrl); + iconTexture.wrapS = THREE.RepeatWrapping; + iconTexture.wrapT = THREE.RepeatWrapping; + iconTexture.anisotropy = 16; + + const avatarMaterial = new THREE.MeshBasicMaterial({ + map: iconTexture, + side: THREE.DoubleSide, + alphaTest: 0.5 + }); + + const iconGeometry = new THREE.PlaneGeometry(1, 1); + + const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial); + avatarObject.position.set(-3, 2.5, 2); + avatarObject.rotation.y = Math.PI / 2; + avatarObject.castShadow = false; + + this.scene.add(avatarObject); + //#endregion + + //#region Username + const name = user.username; + + new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => { + const nameGeometry = new THREE.TextGeometry(name, { + size: 0.5, + height: 0, + curveSegments: 8, + font: font, + bevelThickness: 0, + bevelSize: 0, + bevelEnabled: false + }); + + const nameMaterial = new THREE.MeshLambertMaterial({ + color: 0xffffff + }); + + const nameObject = new THREE.Mesh(nameGeometry, nameMaterial); + nameObject.position.set(-3, 2.25, 1.25); + nameObject.rotation.y = Math.PI / 2; + nameObject.castShadow = false; + + this.scene.add(nameObject); + }); + //#endregion + //#endregion + + //#region Interaction + if (isMyRoom) { + this.furnitureControl = new TransformControls(this.camera, this.canvas); + this.scene.add(this.furnitureControl); + + // Hover highlight + this.canvas.onmousemove = this.onmousemove; + + // Click + this.canvas.onmousedown = this.onmousedown; + } + //#endregion + + //#region Init room + this.loadRoom(); + //#endregion + + //#region Load furnitures + for (const furniture of this.furnitures) { + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + //#endregion + + // Start render + if (this.usePostFXs) { + this.renderWithPostFXs(); + } else { + this.renderWithoutPostFXs(); + } + } + + @autobind + private renderWithoutPostFXs() { + this.renderFrameRequestId = + window.requestAnimationFrame(this.renderWithoutPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.render(this.scene, this.camera); + } + + @autobind + private renderWithPostFXs() { + this.renderFrameRequestId = + window.requestAnimationFrame(this.renderWithPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.clear(); + this.composer.render(); + } + + @autobind + private loadRoom() { + const type = this.roomInfo.roomType; + new GLTFLoader().load(`/assets/room/rooms/${type}/${type}.glb`, gltf => { + gltf.scene.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + + child.receiveShadow = this.enableShadow; + + child.material = new THREE.MeshLambertMaterial({ + color: (child.material as THREE.MeshStandardMaterial).color, + map: (child.material as THREE.MeshStandardMaterial).map, + name: (child.material as THREE.MeshStandardMaterial).name, + }); + + // 異方性フィルタリング + if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; + } + }); + + gltf.scene.position.set(0, 0, 0); + + this.scene.add(gltf.scene); + this.roomObj = gltf.scene; + if (this.roomInfo.roomType === 'default') { + this.applyCarpetColor(); + } + }); + } + + @autobind + private loadFurniture(furniture: Furniture) { + const def = furnitureDefs.find(d => d.id === furniture.type); + return new Promise<GLTF>((res, rej) => { + const loader = new GLTFLoader(); + loader.load(`/assets/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => { + const model = gltf.scene; + + // Load animation + if (gltf.animations.length > 0) { + const mixer = new THREE.AnimationMixer(model); + this.mixers.push(mixer); + for (const clip of gltf.animations) { + mixer.clipAction(clip).play(); + } + } + + model.name = furniture.id; + model.position.x = furniture.position.x; + model.position.y = furniture.position.y; + model.position.z = furniture.position.z; + model.rotation.x = furniture.rotation.x; + model.rotation.y = furniture.rotation.y; + model.rotation.z = furniture.rotation.z; + + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + child.castShadow = this.enableShadow; + child.receiveShadow = this.enableShadow; + (child.material as THREE.MeshStandardMaterial).metalness = 0; + + // 異方性フィルタリング + if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshStandardMaterial).map.anisotropy = 8; + } + }); + + if (def.color) { // カスタムカラー + this.applyCustomColor(model); + } + + if (def.texture) { // カスタムテクスチャ + this.applyCustomTexture(model); + } + + res(gltf); + }, null, rej); + }); + } + + @autobind + private applyCarpetColor() { + this.roomObj.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + if (child.material && + (child.material as THREE.MeshStandardMaterial).name && + (child.material as THREE.MeshStandardMaterial).name === 'Carpet' + ) { + const colorHex = parseInt(this.roomInfo.carpetColor.substr(1), 16); + (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); + } + }); + } + + @autobind + private applyCustomColor(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.color == null) return; + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.color)) { + if (!child.material || + !(child.material as THREE.MeshStandardMaterial).name || + (child.material as THREE.MeshStandardMaterial).name !== t + ) continue; + + const prop = def.color[t]; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + const colorHex = parseInt(val.substr(1), 16); + (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); + } + }); + } + + @autobind + private applyCustomTexture(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.texture == null) return; + + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.texture)) { + if (child.name !== t) continue; + + const prop = def.texture[t].prop; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + const canvas = document.createElement('canvas'); + canvas.height = 1024; + canvas.width = 1024; + + child.material = new THREE.MeshLambertMaterial({ + emissive: 0x111111, + side: THREE.DoubleSide, + alphaTest: 0.5, + }); + + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => { + const uvInfo = def.texture[t].uv; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, + 0, 0, img.width, img.height, + uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height); + + const texture = new THREE.Texture(canvas); + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + texture.anisotropy = 16; + texture.flipY = false; + + (child.material as THREE.MeshLambertMaterial).map = texture; + (child.material as THREE.MeshLambertMaterial).needsUpdate = true; + (child.material as THREE.MeshLambertMaterial).map.needsUpdate = true; + }; + img.src = val; + } + }); + } + + @autobind + private onmousemove(ev: MouseEvent) { + if (this.isTransformMode) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1; + const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + if (this.isSelectedObject(object)) continue; + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const intersected = this.getRoot(intersects[0].object); + if (this.isSelectedObject(intersected)) return; + intersected.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919); + } + }); + } + } + + @autobind + private onmousedown(ev: MouseEvent) { + if (this.isTransformMode) return; + if (ev.target !== this.canvas || ev.button !== 0) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1; + const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const selectedObj = this.getRoot(intersects[0].object); + this.selectFurniture(selectedObj); + } else { + this.selectedObject = null; + this.onChangeSelect(null); + } + } + + @autobind + private getRoot(obj: THREE.Object3D): THREE.Object3D { + let found = false; + let x = obj.parent; + while (!found) { + if (x.parent.parent == null) { + found = true; + } else { + x = x.parent; + } + } + return x; + } + + @autobind + private isSelectedObject(obj: THREE.Object3D): boolean { + if (this.selectedObject == null) { + return false; + } else { + return obj.name === this.selectedObject.name; + } + } + + @autobind + private selectFurniture(obj: THREE.Object3D) { + this.selectedObject = obj; + this.onChangeSelect(obj); + obj.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000); + } + }); + } + + /** + * 家具の移動/回転モードにします + * @param type 移動か回転か + */ + @autobind + public enterTransformMode(type: 'translate' | 'rotate') { + this.isTransformMode = true; + this.furnitureControl.setMode(type); + this.furnitureControl.attach(this.selectedObject); + this.controls.enableRotate = false; + } + + /** + * 家具の移動/回転モードを終了します + */ + @autobind + public exitTransformMode() { + this.isTransformMode = false; + this.furnitureControl.detach(); + this.controls.enableRotate = true; + } + + /** + * 家具プロパティを更新します + * @param key プロパティ名 + * @param value 値 + */ + @autobind + public updateProp(key: string, value: any) { + const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name); + if (furniture.props == null) furniture.props = {}; + furniture.props[key] = value; + this.applyCustomColor(this.selectedObject); + this.applyCustomTexture(this.selectedObject); + } + + /** + * 部屋に家具を追加します + * @param type 家具の種類 + */ + @autobind + public addFurniture(type: string) { + const furniture = { + id: uuid(), + type: type, + position: { + x: 0, + y: 0, + z: 0, + }, + rotation: { + x: 0, + y: 0, + z: 0, + }, + }; + + this.furnitures.push(furniture); + + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + + /** + * 現在選択されている家具を部屋から削除します + */ + @autobind + public removeFurniture() { + this.exitTransformMode(); + const obj = this.selectedObject; + this.scene.remove(obj); + this.objects = this.objects.filter(object => object.name !== obj.name); + this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name); + this.selectedObject = null; + this.onChangeSelect(null); + } + + /** + * 全ての家具を部屋から削除します + */ + @autobind + public removeAllFurnitures() { + this.exitTransformMode(); + for (const obj of this.objects) { + this.scene.remove(obj); + } + this.objects = []; + this.furnitures = []; + this.selectedObject = null; + this.onChangeSelect(null); + } + + /** + * 部屋の床の色を変更します + * @param color 色 + */ + @autobind + public updateCarpetColor(color: string) { + this.roomInfo.carpetColor = color; + this.applyCarpetColor(); + } + + /** + * 部屋の種類を変更します + * @param type 種類 + */ + @autobind + public changeRoomType(type: string) { + this.roomInfo.roomType = type; + this.scene.remove(this.roomObj); + this.loadRoom(); + } + + /** + * 部屋データを取得します + */ + @autobind + public getRoomInfo() { + for (const obj of this.objects) { + const furniture = this.furnitures.find(f => f.id === obj.name); + furniture.position.x = obj.position.x; + furniture.position.y = obj.position.y; + furniture.position.z = obj.position.z; + furniture.rotation.x = obj.rotation.x; + furniture.rotation.y = obj.rotation.y; + furniture.rotation.z = obj.rotation.z; + } + + return this.roomInfo; + } + + /** + * 選択されている家具を取得します + */ + @autobind + public getSelectedObject() { + return this.selectedObject; + } + + @autobind + public findFurnitureById(id: string) { + return this.furnitures.find(furniture => furniture.id === id); + } + + /** + * レンダリングを終了します + */ + @autobind + public destroy() { + // Stop render loop + window.cancelAnimationFrame(this.renderFrameRequestId); + + this.controls.dispose(); + this.scene.dispose(); + } +} diff --git a/src/client/store.ts b/src/client/store.ts index 23c8001846..c1d7d39910 100644 --- a/src/client/store.ts +++ b/src/client/store.ts @@ -56,6 +56,8 @@ export const defaultDeviceSettings = { imageNewTab: false, showFixedPostForm: false, disablePagesScript: true, + roomGraphicsQuality: 'medium', + roomUseOrthographicCamera: true, sfxVolume: 0.3, sfxNote: 'syuilo/down', sfxNoteMy: 'syuilo/up', @@ -187,6 +189,12 @@ export default () => new Vuex.Store({ icon: faTerminal, to: '/scratchpad', }, + rooms: { + title: 'rooms', + icon: faDoorClosed, + get show() { return getters.isSignedIn; }, + get to() { return `/@${state.i.username}/room`; }, + }, }), }, |