Compare commits

..

21 Commits

Author SHA1 Message Date
syuilo
6f1048c006 11.29.0 2019-08-19 12:39:26 +09:00
syuilo
d686e70f2b [Room] Better rendering 2019-08-19 12:35:18 +09:00
syuilo
70f524b82d New Crowdin translations (#5312)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Traditional)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2019-08-19 12:17:37 +09:00
syuilo
79c6475028 Improve readability 2019-08-19 02:19:37 +09:00
syuilo
7dee5309dc Refactoring 2019-08-19 02:06:37 +09:00
syuilo
958ec7b03f Fix #5307 2019-08-19 02:02:10 +09:00
syuilo
9153434906 [Room] Add bin 2019-08-19 01:54:06 +09:00
syuilo
3a08364c24 [Room] Add some furnitures 2019-08-19 01:45:20 +09:00
syuilo
a9beeab502 [Room] Better rendering 2019-08-19 01:43:45 +09:00
syuilo
38c901069a [Room] Better avatar rendering 2019-08-19 01:15:30 +09:00
syuilo
3f7606060e Update geometry name 2019-08-19 01:01:15 +09:00
kabo2468
777f20e9be Add Trash can (#5309)
new file:   src/client/assets/room/furnitures/trash-can/trash-can.blend
	new file:   src/client/assets/room/furnitures/trash-can/trash-can.glb
2019-08-19 00:51:57 +09:00
Aya Morisawa
8e39aecffe Update room section of CONTRIBUTING.md (#5306)
* Update room section of CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md
2019-08-18 23:40:52 +09:00
syuilo
9e1ab54097 11.28.2 2019-08-18 20:32:23 +09:00
syuilo
0f9e09f4bd cors 2019-08-18 20:32:04 +09:00
MeiMei
743ebc17b9 Fix #5291 (#5294) 2019-08-18 20:25:12 +09:00
syuilo
9bc4af76b8 モバイルでもRoomを表示できるように 2019-08-18 19:11:24 +09:00
syuilo
46fa26426d Fix bug 2019-08-18 19:08:33 +09:00
syuilo
58d0dc1795 11.28.1 2019-08-18 16:56:42 +09:00
syuilo
bc11702f7d Fix #5290 2019-08-18 16:55:09 +09:00
syuilo
6288de5813 Fix #5291 2019-08-18 16:51:27 +09:00
30 changed files with 350 additions and 53 deletions

View File

@@ -1,6 +1,30 @@
ChangeLog ChangeLog
========= =========
11.29.0 (2019/08/19)
--------------------
### ✨Improvements
* Room: ソファ追加
* Room: 螺旋階段追加
* Room: ゴミ箱追加
### 🐛Fixes
* Room: 部屋を離れても裏でレンダリングが続く問題を修正
* Room: アバターのレンダリングを修正
* Room: ライティングの調整
11.28.2 (2019/08/18)
--------------------
### 🐛Fixes
* 他人の部屋なのに部屋編集UIが表示されるのを修正
* オブジェクトストレージを使用している場合Roomで画像を読み込めない問題を修正
11.28.1 (2019/08/18)
--------------------
### 🐛Fixes
* オブジェクトストレージを使用している場合Roomで画像を読み込めない問題を修正
* Roomで家具を移動など確定せずに「しまう」と部屋ごと消える問題を修正
11.28.0 (2019/08/18) 11.28.0 (2019/08/18)
-------------------- --------------------
### ✨Improvements ### ✨Improvements

View File

@@ -39,13 +39,12 @@ Misskey uses CircleCI for executing automated tests.
Configuration files are located in [`/.circleci`](/.circleci). Configuration files are located in [`/.circleci`](/.circleci).
## Adding MisskeyRoom items ## Adding MisskeyRoom items
Currently, we accept only 3D models created with [Blender](https://www.blender.org/).
* Use English for material, object and texture names * Use English for material, object and texture names
* Use meter for unit of length * Use meter for unit of length
* Your PR must include all source files of your models (for later editing) * Your PR should include all source files of your models (for later editing)
* Your PR must include the glTF binary files (.glb) of your models * Your PR must include the glTF binary files (.glb) of your models
If you have no experience on 3D modeling, we suggest to use the free 3DCG software [Blender](https://www.blender.org/).
You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html). You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html).
## FAQ ## FAQ

View File

@@ -1355,3 +1355,4 @@ room:
save: "Uložit" save: "Uložit"
furnitures: furnitures:
moon: "Po" moon: "Po"
bin: "Koš"

View File

@@ -1915,3 +1915,4 @@ room:
save: "Gem" save: "Gem"
furnitures: furnitures:
moon: "Man" moon: "Man"
bin: "Skraldespand"

View File

@@ -950,3 +950,4 @@ room:
save: "Speichern" save: "Speichern"
furnitures: furnitures:
moon: "Mo" moon: "Mo"
bin: "Papierkorb"

View File

@@ -296,6 +296,16 @@ common:
saved: "Saved" saved: "Saved"
home-profile: "Home profile" home-profile: "Home profile"
deck-profile: "Deck profile" deck-profile: "Deck profile"
room: "Room"
_room:
graphicsQuality: "Graphics Quality"
_graphicsQuality:
ultra: "Ultra"
high: "High"
medium: "Medium"
low: "Low"
cheep: "Cheep"
useOrthographicCamera: "Use Orthographic Camera"
search: "Search" search: "Search"
delete: "Delete" delete: "Delete"
loading: "Loading" loading: "Loading"
@@ -1135,6 +1145,7 @@ desktop/views/components/ui.header.account.vue:
groups: "Groups" groups: "Groups"
follow-requests: "Follow requests" follow-requests: "Follow requests"
admin: "Admin" admin: "Admin"
room: "Room"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
game: "Games" game: "Games"
desktop/views/components/ui.header.notifications.vue: desktop/views/components/ui.header.notifications.vue:
@@ -2075,7 +2086,54 @@ pages:
pageVariables: "Page element" pageVariables: "Page element"
argVariables: "Input slot" argVariables: "Input slot"
room: room:
add-furniture: "Place furniture"
translate: "Move" translate: "Move"
rotate: "Rotate"
exit: "Deselect"
remove: "Remove"
save: "Save" save: "Save"
chooseImage: "Select an image"
room-type: "Room type"
carpet-color: "Color of carpet"
rooms:
default: "Default"
washitsu: "Japanese-style"
furnitures: furnitures:
milk: "Milk carton"
bed: "Bed"
low-table: "Low Table"
desk: "Desk"
chair: "Chair"
chair2: "Chair 2"
fan: "Fan"
pc: "Computer"
plant: "Houseplant"
plant2: "Houseplant 2"
eraser: "Eraser"
pencil: "Pencil"
pudding: "Pudding"
cardboard-box: "Cardboard Box"
cardboard-box2: "Cardboard Box 2"
cardboard-box3: "Cardboard Box 3"
book: "Book"
book2: "Book 2"
piano: "Piano"
facial-tissue: "Facial tissue"
server: "Servers"
moon: "M" moon: "M"
corkboard: "Cork board"
mousepad: "Mousepad"
monitor: "Monitor"
keyboard: "Keyboard"
carpet-stripe: "Carpet (stripe)"
mat: "Mat"
color-box: "Bookshelf"
wall-clock: "Wall clock"
photoframe: "Picture frame"
cube: "Cube"
tv: "TV"
pinguin: "Penguin"
rubik-cube: "Rubik's Cube"
poster-h: "Poster (Horizontal)"
poster-v: "Poster (Vertical)"
bin: "Trash"

View File

@@ -1135,3 +1135,8 @@ pages:
arg1: "Listas" arg1: "Listas"
types: types:
array: "Listas" array: "Listas"
room:
save: "Guardar"
furnitures:
moon: "Luna"
bin: "Papelera"

View File

@@ -2004,3 +2004,4 @@ room:
save: "Enregistrer" save: "Enregistrer"
furnitures: furnitures:
moon: "L" moon: "L"
bin: "Corbeille"

View File

@@ -2344,3 +2344,6 @@ room:
rubik-cube: "ルービックキューブ" rubik-cube: "ルービックキューブ"
poster-h: "ポスター(横長)" poster-h: "ポスター(横長)"
poster-v: "ポスター(縦長)" poster-v: "ポスター(縦長)"
sofa: "ソファ"
spiral: "螺旋階段"
bin: "ゴミ箱"

View File

@@ -1284,3 +1284,9 @@ pages:
arg1: "リスト" arg1: "リスト"
types: types:
array: "リスト" array: "リスト"
room:
translate: "移動"
save: "保存"
furnitures:
moon: "月"
bin: "ゴミ箱"

View File

@@ -296,6 +296,16 @@ common:
saved: "저장하였습니다" saved: "저장하였습니다"
home-profile: "홈 프로필" home-profile: "홈 프로필"
deck-profile: "덱 프로필" deck-profile: "덱 프로필"
room: "룸"
_room:
graphicsQuality: "그래픽 품질"
_graphicsQuality:
ultra: "최고"
high: "높음"
medium: "보통"
low: "낮음"
cheep: "최저"
useOrthographicCamera: "평행 투시 카메라를 사용"
search: "검색" search: "검색"
delete: "삭제" delete: "삭제"
loading: "로드 중" loading: "로드 중"
@@ -1135,6 +1145,7 @@ desktop/views/components/ui.header.account.vue:
groups: "그룹" groups: "그룹"
follow-requests: "팔로우 요청" follow-requests: "팔로우 요청"
admin: "관리" admin: "관리"
room: "룸"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
game: "게임" game: "게임"
desktop/views/components/ui.header.notifications.vue: desktop/views/components/ui.header.notifications.vue:
@@ -2075,7 +2086,54 @@ pages:
pageVariables: "페이지 요소" pageVariables: "페이지 요소"
argVariables: "입력 슬롯" argVariables: "입력 슬롯"
room: room:
add-furniture: "가구를 배치"
translate: "이동" translate: "이동"
rotate: "회전"
exit: "선택 해제"
remove: "치우기"
save: "저장" save: "저장"
chooseImage: "이미지 선택"
room-type: "룸 종류"
carpet-color: "바닥 색상"
rooms:
default: "기본"
washitsu: "일본식"
furnitures: furnitures:
milk: "우유 팩"
bed: "침대"
low-table: "낮은 테이블"
desk: "책상"
chair: "의자"
chair2: "의자 2"
fan: "환기구"
pc: "컴퓨터"
plant: "관엽식물"
plant2: "관엽식물 2"
eraser: "지우개"
pencil: "연필"
pudding: "푸딩"
cardboard-box: "골판지 상자"
cardboard-box2: "골판지 상자 2"
cardboard-box3: "골판지 상자 3"
book: "책"
book2: "책 2"
piano: "피아노"
facial-tissue: "휴지 상자"
server: "서버"
moon: "월" moon: "월"
corkboard: "게시판"
mousepad: "마우스 패드"
monitor: "모니터"
keyboard: "키보드"
carpet-stripe: "카페트 (줄무늬)"
mat: "매트"
color-box: "책장"
wall-clock: "벽걸이 시계"
photoframe: "액자"
cube: "큐브"
tv: "TV"
pinguin: "펭귄"
rubik-cube: "루빅스 큐브"
poster-h: "포스터 (가로)"
poster-v: "포스터 (세로)"
bin: "휴지통"

View File

@@ -520,3 +520,9 @@ pages:
arg1: "Lister" arg1: "Lister"
types: types:
array: "Lister" array: "Lister"
room:
translate: "Flytt"
save: "Lagre"
furnitures:
moon: "Måne"
bin: "Papirkurv"

View File

@@ -1261,3 +1261,4 @@ room:
save: "Zapisz" save: "Zapisz"
furnitures: furnitures:
moon: "Pn" moon: "Pn"
bin: "Kosz"

View File

@@ -284,3 +284,7 @@ pages:
blocks: blocks:
image: "Imagens" image: "Imagens"
post: "Formulário de publicação" post: "Formulário de publicação"
room:
furnitures:
moon: "Lua"
bin: "Lixo"

View File

@@ -168,3 +168,7 @@ pages:
random: "Случайно" random: "Случайно"
blocks: blocks:
random: "Случайно" random: "Случайно"
room:
furnitures:
moon: "Луна"
bin: "Мусорное ведро"

View File

@@ -296,6 +296,16 @@ common:
saved: "已保存" saved: "已保存"
home-profile: "定制首页数据" home-profile: "定制首页数据"
deck-profile: "定制Deck数据" deck-profile: "定制Deck数据"
room: "房间"
_room:
graphicsQuality: "图形质量"
_graphicsQuality:
ultra: "最高"
high: "高"
medium: "中"
low: "低"
cheep: "最低"
useOrthographicCamera: "使用正交相机"
search: "搜索" search: "搜索"
delete: "删除" delete: "删除"
loading: "正在加载中" loading: "正在加载中"
@@ -1135,6 +1145,7 @@ desktop/views/components/ui.header.account.vue:
groups: "群组" groups: "群组"
follow-requests: "关注申请" follow-requests: "关注申请"
admin: "管理" admin: "管理"
room: "房间"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
game: "游戏" game: "游戏"
desktop/views/components/ui.header.notifications.vue: desktop/views/components/ui.header.notifications.vue:
@@ -2075,7 +2086,54 @@ pages:
pageVariables: "页面元素" pageVariables: "页面元素"
argVariables: "输入槽函数" argVariables: "输入槽函数"
room: room:
add-furniture: "放置家具"
translate: "移动" translate: "移动"
rotate: "旋转"
exit: "返回"
remove: "移除"
save: "保存" save: "保存"
chooseImage: "选择图片"
room-type: "房间类型"
carpet-color: "地板颜色"
rooms:
default: "默认"
washitsu: "和式房间"
furnitures: furnitures:
milk: "牛奶纸箱"
bed: "床"
low-table: "矮桌"
desk: "书桌"
chair: "椅子"
chair2: "椅子2"
fan: "换气扇"
pc: "电脑"
plant: "观叶植物"
plant2: "观叶植物2"
eraser: "橡皮擦"
pencil: "铅笔"
pudding: "布丁"
cardboard-box: "纸板箱"
cardboard-box2: "纸板箱2"
cardboard-box3: "纸板箱3"
book: "书"
book2: "书2"
piano: "钢琴"
facial-tissue: "纸巾盒"
server: "服务器"
moon: "一" moon: "一"
corkboard: "软木板"
mousepad: "鼠标垫"
monitor: "显示器"
keyboard: "键盘"
carpet-stripe: "地毯(条纹)"
mat: "垫子"
color-box: "彩盒"
wall-clock: "挂钟"
photoframe: "相框"
cube: "立方体"
tv: "电视"
pinguin: "企鹅君"
rubik-cube: "魔方"
poster-h: "海报(横向)"
poster-v: "海报(纵向)"
bin: "垃圾箱"

View File

@@ -88,3 +88,6 @@ admin/views/charts.vue:
drive: "雲端硬碟" drive: "雲端硬碟"
pages: pages:
like: "贊" like: "贊"
room:
furnitures:
moon: "月"

View File

@@ -1,7 +1,7 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "11.28.0", "version": "11.29.0",
"codename": "daybreak", "codename": "daybreak",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -321,4 +321,34 @@
}, },
}, },
}, },
{
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'
}
},
] ]

View File

@@ -1,4 +1,5 @@
import autobind from 'autobind-decorator'; import autobind from 'autobind-decorator';
import { v4 as uuid } from 'uuid';
import * as THREE from 'three'; import * as THREE from 'three';
import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
@@ -9,7 +10,7 @@ import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js';
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
import { Furniture, RoomInfo } from './furniture'; import { Furniture, RoomInfo } from './furniture';
import { v4 as uuid } from 'uuid'; import { query as urlQuery } from '../../../../../prelude/url';
const furnitureDefs = require('./furnitures.json5'); const furnitureDefs = require('./furnitures.json5');
THREE.ImageUtils.crossOrigin = ''; THREE.ImageUtils.crossOrigin = '';
@@ -20,6 +21,9 @@ type Options = {
useOrthographicCamera: boolean; useOrthographicCamera: boolean;
}; };
/**
* MisskeyRoom Core Engine
*/
export class Room { export class Room {
private clock: THREE.Clock; private clock: THREE.Clock;
private scene: THREE.Scene; private scene: THREE.Scene;
@@ -36,7 +40,11 @@ export class Room {
private selectedObject: THREE.Object3D = null; private selectedObject: THREE.Object3D = null;
private onChangeSelect: Function; private onChangeSelect: Function;
private isTransformMode = false; private isTransformMode = false;
public canvas: HTMLCanvasElement; private renderFrameRequestId: number;
private get canvas(): HTMLCanvasElement {
return this.renderer.domElement;
}
private get furnitures(): Furniture[] { private get furnitures(): Furniture[] {
return this.roomInfo.furnitures; return this.roomInfo.furnitures;
@@ -102,8 +110,7 @@ export class Room {
this.graphicsQuality === 'low' ? THREE.BasicShadowMap : this.graphicsQuality === 'low' ? THREE.BasicShadowMap :
THREE.BasicShadowMap; // cheep THREE.BasicShadowMap; // cheep
this.canvas = this.renderer.domElement; container.appendChild(this.canvas);
container.appendChild(this.renderer.domElement);
//#endregion //#endregion
//#region Init a camera //#region Init a camera
@@ -150,22 +157,29 @@ export class Room {
} }
//#region Out light //#region Out light
const outLight = new THREE.SpotLight(0xffffff, 0.4); 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);
outLight.position.set(9, 3, -2); const outLight2 = new THREE.SpotLight(0xffffff, 0.2);
outLight.castShadow = this.enableShadow; outLight2.position.set(-2, 3, 9);
outLight.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある outLight2.castShadow = false;
outLight.shadow.mapSize.width = this.shadowQuality; outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある
outLight.shadow.mapSize.height = this.shadowQuality; outLight2.shadow.camera.near = 6;
outLight.shadow.camera.near = 6; outLight2.shadow.camera.far = 15;
outLight.shadow.camera.far = 15; outLight2.shadow.camera.fov = 45;
outLight.shadow.camera.fov = 45; this.scene.add(outLight2);
this.scene.add(outLight);
//#endregion //#endregion
//#region Init a controller //#region Init a controller
this.controls = new OrbitControls(this.camera, this.renderer.domElement); this.controls = new OrbitControls(this.camera, this.canvas);
this.controls.target.set(0, 1, 0); this.controls.target.set(0, 1, 0);
this.controls.enableZoom = true; this.controls.enableZoom = true;
@@ -208,15 +222,17 @@ export class Room {
//#region Label //#region Label
//#region Avatar //#region Avatar
const avatarUrl = user.avatarUrl; const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`;
const iconTexture = new THREE.TextureLoader().load(avatarUrl); const textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = 'anonymous';
const iconTexture = textureLoader.load(avatarUrl);
iconTexture.wrapS = THREE.RepeatWrapping; iconTexture.wrapS = THREE.RepeatWrapping;
iconTexture.wrapT = THREE.RepeatWrapping; iconTexture.wrapT = THREE.RepeatWrapping;
iconTexture.anisotropy = 16; iconTexture.anisotropy = 16;
const avatarMaterial = new THREE.MeshLambertMaterial({ const avatarMaterial = new THREE.MeshBasicMaterial({
emissive: 0x111111,
map: iconTexture, map: iconTexture,
side: THREE.DoubleSide, side: THREE.DoubleSide,
alphaTest: 0.5 alphaTest: 0.5
@@ -262,14 +278,14 @@ export class Room {
//#region Interaction //#region Interaction
if (isMyRoom) { if (isMyRoom) {
this.furnitureControl = new TransformControls(this.camera, this.renderer.domElement); this.furnitureControl = new TransformControls(this.camera, this.canvas);
this.scene.add(this.furnitureControl); this.scene.add(this.furnitureControl);
// Hover highlight // Hover highlight
this.renderer.domElement.onmousemove = this.onmousemove; this.canvas.onmousemove = this.onmousemove;
// Click // Click
this.renderer.domElement.onmousedown = this.onmousedown; this.canvas.onmousedown = this.onmousedown;
} }
//#endregion //#endregion
@@ -296,7 +312,8 @@ export class Room {
@autobind @autobind
private renderWithoutPostFXs() { private renderWithoutPostFXs() {
requestAnimationFrame(this.renderWithoutPostFXs); this.renderFrameRequestId =
window.requestAnimationFrame(this.renderWithoutPostFXs);
// Update animations // Update animations
const clock = this.clock.getDelta(); const clock = this.clock.getDelta();
@@ -310,7 +327,8 @@ export class Room {
@autobind @autobind
private renderWithPostFXs() { private renderWithPostFXs() {
requestAnimationFrame(this.renderWithPostFXs); this.renderFrameRequestId =
window.requestAnimationFrame(this.renderWithPostFXs);
// Update animations // Update animations
const clock = this.clock.getDelta(); const clock = this.clock.getDelta();
@@ -384,17 +402,13 @@ export class Room {
if (!(child instanceof THREE.Mesh)) return; if (!(child instanceof THREE.Mesh)) return;
child.castShadow = this.enableShadow; child.castShadow = this.enableShadow;
child.receiveShadow = this.enableShadow; child.receiveShadow = this.enableShadow;
child.material = new THREE.MeshLambertMaterial({ (child.material as THREE.MeshStandardMaterial).metalness = 0;
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') { if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') {
(child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; (child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; (child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; (child.material as THREE.MeshStandardMaterial).map.anisotropy = 8;
} }
}); });
@@ -446,6 +460,7 @@ export class Room {
const furniture = this.furnitures.find(furniture => furniture.id === model.name); const furniture = this.furnitures.find(furniture => furniture.id === model.name);
const def = furnitureDefs.find(d => d.id === furniture.type); const def = furnitureDefs.find(d => d.id === furniture.type);
if (def.texture == null) return; if (def.texture == null) return;
model.traverse(child => { model.traverse(child => {
if (!(child instanceof THREE.Mesh)) return; if (!(child instanceof THREE.Mesh)) return;
for (const t of Object.keys(def.texture)) { for (const t of Object.keys(def.texture)) {
@@ -467,6 +482,7 @@ export class Room {
}); });
const img = new Image(); const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => { img.onload = () => {
const uvInfo = def.texture[t].uv; const uvInfo = def.texture[t].uv;
@@ -493,8 +509,8 @@ export class Room {
if (this.isTransformMode) return; if (this.isTransformMode) return;
const rect = (ev.target as HTMLElement).getBoundingClientRect(); const rect = (ev.target as HTMLElement).getBoundingClientRect();
const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.renderer.domElement.width) * 2 - 1; const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1;
const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.renderer.domElement.height) * 2 + 1; const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1;
const pos = new THREE.Vector2(x, y); const pos = new THREE.Vector2(x, y);
this.camera.updateMatrixWorld(); this.camera.updateMatrixWorld();
@@ -515,7 +531,7 @@ export class Room {
if (intersects.length > 0) { if (intersects.length > 0) {
const intersected = this.getRoot(intersects[0].object); const intersected = this.getRoot(intersects[0].object);
if (!this.isSelectedObject(intersected)) { if (this.isSelectedObject(intersected)) return;
intersected.traverse(child => { intersected.traverse(child => {
if (child instanceof THREE.Mesh) { if (child instanceof THREE.Mesh) {
(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919); (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919);
@@ -523,16 +539,15 @@ export class Room {
}); });
} }
} }
}
@autobind @autobind
private onmousedown(ev: MouseEvent) { private onmousedown(ev: MouseEvent) {
if (this.isTransformMode) return; if (this.isTransformMode) return;
if (ev.target !== this.renderer.domElement || ev.button !== 0) return; if (ev.target !== this.canvas || ev.button !== 0) return;
const rect = (ev.target as HTMLElement).getBoundingClientRect(); const rect = (ev.target as HTMLElement).getBoundingClientRect();
const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.renderer.domElement.width) * 2 - 1; const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1;
const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.renderer.domElement.height) * 2 + 1; const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1;
const pos = new THREE.Vector2(x, y); const pos = new THREE.Vector2(x, y);
this.camera.updateMatrixWorld(); this.camera.updateMatrixWorld();
@@ -642,6 +657,7 @@ export class Room {
@autobind @autobind
public removeFurniture() { public removeFurniture() {
this.exitTransformMode();
const obj = this.selectedObject; const obj = this.selectedObject;
this.scene.remove(obj); this.scene.remove(obj);
this.objects = this.objects.filter(object => object.name !== obj.name); this.objects = this.objects.filter(object => object.name !== obj.name);
@@ -687,4 +703,10 @@ export class Room {
public findFurnitureById(id: string) { public findFurnitureById(id: string) {
return this.furnitures.find(furniture => furniture.id === id); return this.furnitures.find(furniture => furniture.id === id);
} }
@autobind
public destroy() {
// Stop render loop
window.cancelAnimationFrame(this.renderFrameRequestId);
}
} }

View File

@@ -25,7 +25,8 @@
<ui-button @click="remove()"><fa :icon="faTrashAlt"/> {{ $t('remove') }}</ui-button> <ui-button @click="remove()"><fa :icon="faTrashAlt"/> {{ $t('remove') }}</ui-button>
</section> </section>
</div> </div>
<div class="menu">
<div class="menu" v-if="isMyRoom">
<section> <section>
<ui-button @click="add()"><fa :icon="faBoxOpen"/> {{ $t('add-furniture') }}</ui-button> <ui-button @click="add()"><fa :icon="faBoxOpen"/> {{ $t('add-furniture') }}</ui-button>
</section> </section>
@@ -56,6 +57,7 @@ import XPreview from './preview.vue';
const storeItems = require('../../../scripts/room/furnitures.json5'); const storeItems = require('../../../scripts/room/furnitures.json5');
import { faBoxOpen, faUndo, faArrowsAlt, faBan } from '@fortawesome/free-solid-svg-icons'; import { faBoxOpen, faUndo, faArrowsAlt, faBan } from '@fortawesome/free-solid-svg-icons';
import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons'; import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import { query as urlQuery } from '../../../../../../prelude/url';
let room: Room; let room: Room;
@@ -83,6 +85,7 @@ export default Vue.extend({
carpetColor: null, carpetColor: null,
isTranslateMode: false, isTranslateMode: false,
isRotateMode: false, isRotateMode: false,
isMyRoom: false,
faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan, faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan,
}; };
}, },
@@ -92,6 +95,8 @@ export default Vue.extend({
...parseAcct(this.acct) ...parseAcct(this.acct)
}); });
this.isMyRoom = this.$store.getters.isSignedIn && this.$store.state.i.id === user.id;
const roomInfo = await this.$root.api('room/show', { const roomInfo = await this.$root.api('room/show', {
userId: user.id userId: user.id
}); });
@@ -99,7 +104,7 @@ export default Vue.extend({
this.roomType = roomInfo.roomType; this.roomType = roomInfo.roomType;
this.carpetColor = roomInfo.carpetColor; this.carpetColor = roomInfo.carpetColor;
room = new Room(user, this.$store.getters.isSignedIn && this.$store.state.i.id === user.id, roomInfo, this.$el, { room = new Room(user, this.isMyRoom, roomInfo, this.$el, {
graphicsQuality: this.$store.state.device.roomGraphicsQuality, graphicsQuality: this.$store.state.device.roomGraphicsQuality,
onChangeSelect: obj => { onChangeSelect: obj => {
this.objectSelected = obj != null; this.objectSelected = obj != null;
@@ -119,6 +124,10 @@ export default Vue.extend({
}); });
}, },
beforeDestroy() {
room.destroy();
},
methods: { methods: {
async add() { async add() {
const { canceled, result: id } = await this.$root.dialog({ const { canceled, result: id } = await this.$root.dialog({
@@ -136,6 +145,8 @@ export default Vue.extend({
}, },
remove() { remove() {
this.isTranslateMode = false;
this.isRotateMode = false;
room.removeFurniture(); room.removeFurniture();
}, },
@@ -149,7 +160,7 @@ export default Vue.extend({
this.$chooseDriveFile({ this.$chooseDriveFile({
multiple: false multiple: false
}).then(file => { }).then(file => {
room.updateProp(key, file.thumbnailUrl); room.updateProp(key, `/proxy/?${urlQuery({ url: file.thumbnailUrl })}`);
this.$refs.preview.selected(room.getSelectedObject()); this.$refs.preview.selected(room.getSelectedObject());
}); });
}, },

View File

@@ -171,6 +171,7 @@ init((launch, os) => {
]}, ]},
{ path: '/@:user/pages/:page', component: UI, props: route => ({ component: () => import('../common/views/pages/page.vue').then(m => m.default), pageName: route.params.page, username: route.params.user }) }, { path: '/@:user/pages/:page', component: UI, props: route => ({ component: () => import('../common/views/pages/page.vue').then(m => m.default), pageName: route.params.page, username: route.params.user }) },
{ path: '/@:user/pages/:pageName/view-source', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), initUser: route.params.user, initPageName: route.params.pageName }) }, { path: '/@:user/pages/:pageName/view-source', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), initUser: route.params.user, initPageName: route.params.pageName }) },
{ path: '/@:acct/room', props: true, component: () => import('../common/views/pages/room/room.vue').then(m => m.default) },
{ path: '/notes/:note', component: MkNote }, { path: '/notes/:note', component: MkNote },
{ path: '/authorize-follow', component: MkFollow }, { path: '/authorize-follow', component: MkFollow },
{ path: '*', component: MkNotFound } { path: '*', component: MkNotFound }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.