feat: support poses library

dev-postmessage-to-online
Yu Zhu 2023-03-15 22:16:08 +08:00
parent 691d0a9d4c
commit 9432490f9c
14 changed files with 100628 additions and 66 deletions

24
compress.ts Normal file
View File

@ -0,0 +1,24 @@
import avsc from 'avsc'
import fs from 'fs-extra'
const data = fs.readJSONSync('src/poses/data.json')
const data0: [number, number, number][][] = data
.map((i) =>
i.map((value) => {
if (value) {
return [
Math.round(value[0] * 1000),
Math.round(value[1] * 1000),
Math.round(value[2] * 1000),
]
} else return [0, 0, 0]
})
)
.filter((i) => {
const [a, b, c] = i[1]
return b > 30 * 1000
})
const int32Buffer = new Int32Array(data0.flat(2))
fs.writeFileSync('src/poses/data.bin', Buffer.from(int32Buffer.buffer))
console.log(data0.length, int32Buffer.byteLength)

View File

@ -16,6 +16,7 @@
"dayjs": "^1.11.7",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.7.0",
"fs-extra": "^11.1.0",
"i18next": "^22.4.11",
"i18next-browser-languagedetector": "^7.0.1",
"prettier": "^2.8.4",
@ -24,6 +25,7 @@
"rollup-plugin-visualizer": "^5.9.0",
"sweetalert2": "^11.7.3",
"three": "^0.150.1",
"tsx": "^3.12.5",
"type-fest": "^3.6.1",
"vite-plugin-pwa": "^0.14.4",
"workbox-window": "^6.5.4"

View File

@ -12,6 +12,7 @@ specifiers:
dayjs: ^1.11.7
eslint: ^8.35.0
eslint-config-prettier: ^8.7.0
fs-extra: ^11.1.0
i18next: ^22.4.11
i18next-browser-languagedetector: ^7.0.1
prettier: ^2.8.4
@ -20,6 +21,7 @@ specifiers:
rollup-plugin-visualizer: ^5.9.0
sweetalert2: ^11.7.3
three: ^0.150.1
tsx: ^3.12.5
type-fest: ^3.6.1
typescript: ^4.9.3
vite: ^4.1.0
@ -33,6 +35,7 @@ dependencies:
dayjs: 1.11.7
eslint: 8.35.0
eslint-config-prettier: 8.7.0_eslint@8.35.0
fs-extra: 11.1.0
i18next: 22.4.11
i18next-browser-languagedetector: 7.0.1
prettier: 2.8.4
@ -41,6 +44,7 @@ dependencies:
rollup-plugin-visualizer: 5.9.0
sweetalert2: 11.7.3
three: 0.150.1
tsx: 3.12.5
type-fest: 3.6.1
vite-plugin-pwa: 0.14.4_pchkumgzq6po4w4enhsumrku2u
workbox-window: 6.5.4
@ -1219,6 +1223,27 @@ packages:
'@babel/helper-validator-identifier': 7.19.1
to-fast-properties: 2.0.0
/@esbuild-kit/cjs-loader/2.4.2:
resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==}
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.4.0
dev: false
/@esbuild-kit/core-utils/3.1.0:
resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==}
dependencies:
esbuild: 0.17.11
source-map-support: 0.5.21
dev: false
/@esbuild-kit/esm-loader/2.5.5:
resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==}
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.4.0
dev: false
/@esbuild/android-arm/0.16.17:
resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==}
engines: {node: '>=12'}
@ -1227,6 +1252,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/android-arm/0.17.11:
resolution: {integrity: sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/android-arm64/0.16.17:
resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==}
engines: {node: '>=12'}
@ -1235,6 +1269,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/android-arm64/0.17.11:
resolution: {integrity: sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/android-x64/0.16.17:
resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==}
engines: {node: '>=12'}
@ -1243,6 +1286,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/android-x64/0.17.11:
resolution: {integrity: sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/darwin-arm64/0.16.17:
resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==}
engines: {node: '>=12'}
@ -1251,6 +1303,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/darwin-arm64/0.17.11:
resolution: {integrity: sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@esbuild/darwin-x64/0.16.17:
resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==}
engines: {node: '>=12'}
@ -1259,6 +1320,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/darwin-x64/0.17.11:
resolution: {integrity: sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@esbuild/freebsd-arm64/0.16.17:
resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==}
engines: {node: '>=12'}
@ -1267,6 +1337,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/freebsd-arm64/0.17.11:
resolution: {integrity: sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/freebsd-x64/0.16.17:
resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==}
engines: {node: '>=12'}
@ -1275,6 +1354,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/freebsd-x64/0.17.11:
resolution: {integrity: sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-arm/0.16.17:
resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==}
engines: {node: '>=12'}
@ -1283,6 +1371,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-arm/0.17.11:
resolution: {integrity: sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-arm64/0.16.17:
resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==}
engines: {node: '>=12'}
@ -1291,6 +1388,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-arm64/0.17.11:
resolution: {integrity: sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-ia32/0.16.17:
resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==}
engines: {node: '>=12'}
@ -1299,6 +1405,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-ia32/0.17.11:
resolution: {integrity: sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-loong64/0.16.17:
resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==}
engines: {node: '>=12'}
@ -1307,6 +1422,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-loong64/0.17.11:
resolution: {integrity: sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-mips64el/0.16.17:
resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==}
engines: {node: '>=12'}
@ -1315,6 +1439,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-mips64el/0.17.11:
resolution: {integrity: sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-ppc64/0.16.17:
resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==}
engines: {node: '>=12'}
@ -1323,6 +1456,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-ppc64/0.17.11:
resolution: {integrity: sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-riscv64/0.16.17:
resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==}
engines: {node: '>=12'}
@ -1331,6 +1473,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-riscv64/0.17.11:
resolution: {integrity: sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-s390x/0.16.17:
resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==}
engines: {node: '>=12'}
@ -1339,6 +1490,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-s390x/0.17.11:
resolution: {integrity: sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-x64/0.16.17:
resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==}
engines: {node: '>=12'}
@ -1347,6 +1507,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/linux-x64/0.17.11:
resolution: {integrity: sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/netbsd-x64/0.16.17:
resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==}
engines: {node: '>=12'}
@ -1355,6 +1524,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/netbsd-x64/0.17.11:
resolution: {integrity: sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/openbsd-x64/0.16.17:
resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==}
engines: {node: '>=12'}
@ -1363,6 +1541,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/openbsd-x64/0.17.11:
resolution: {integrity: sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/sunos-x64/0.16.17:
resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==}
engines: {node: '>=12'}
@ -1371,6 +1558,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/sunos-x64/0.17.11:
resolution: {integrity: sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-arm64/0.16.17:
resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==}
engines: {node: '>=12'}
@ -1379,6 +1575,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/win32-arm64/0.17.11:
resolution: {integrity: sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-ia32/0.16.17:
resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==}
engines: {node: '>=12'}
@ -1387,6 +1592,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/win32-ia32/0.17.11:
resolution: {integrity: sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-x64/0.16.17:
resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==}
engines: {node: '>=12'}
@ -1395,6 +1609,15 @@ packages:
requiresBuild: true
optional: true
/@esbuild/win32-x64/0.17.11:
resolution: {integrity: sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@eslint/eslintrc/2.0.0:
resolution: {integrity: sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -2208,6 +2431,36 @@ packages:
'@esbuild/win32-ia32': 0.16.17
'@esbuild/win32-x64': 0.16.17
/esbuild/0.17.11:
resolution: {integrity: sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.17.11
'@esbuild/android-arm64': 0.17.11
'@esbuild/android-x64': 0.17.11
'@esbuild/darwin-arm64': 0.17.11
'@esbuild/darwin-x64': 0.17.11
'@esbuild/freebsd-arm64': 0.17.11
'@esbuild/freebsd-x64': 0.17.11
'@esbuild/linux-arm': 0.17.11
'@esbuild/linux-arm64': 0.17.11
'@esbuild/linux-ia32': 0.17.11
'@esbuild/linux-loong64': 0.17.11
'@esbuild/linux-mips64el': 0.17.11
'@esbuild/linux-ppc64': 0.17.11
'@esbuild/linux-riscv64': 0.17.11
'@esbuild/linux-s390x': 0.17.11
'@esbuild/linux-x64': 0.17.11
'@esbuild/netbsd-x64': 0.17.11
'@esbuild/openbsd-x64': 0.17.11
'@esbuild/sunos-x64': 0.17.11
'@esbuild/win32-arm64': 0.17.11
'@esbuild/win32-ia32': 0.17.11
'@esbuild/win32-x64': 0.17.11
dev: false
/escalade/3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@ -2436,6 +2689,15 @@ packages:
is-callable: 1.2.7
dev: false
/fs-extra/11.1.0:
resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==}
engines: {node: '>=14.14'}
dependencies:
graceful-fs: 4.2.10
jsonfile: 6.1.0
universalify: 2.0.0
dev: false
/fs-extra/9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
engines: {node: '>=10'}
@ -2503,6 +2765,10 @@ packages:
get-intrinsic: 1.2.0
dev: false
/get-tsconfig/4.4.0:
resolution: {integrity: sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==}
dev: false
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@ -3568,6 +3834,17 @@ packages:
typescript: 4.9.5
dev: false
/tsx/3.12.5:
resolution: {integrity: sha512-/TLj30xF1zcN9JkoFCyROtIQUi8cRQG+AFchsg5YkWou3+RXxTZS/ffWB3nCxyZPoBqF2+8ohs07N815dNb1wQ==}
hasBin: true
dependencies:
'@esbuild-kit/cjs-loader': 2.4.2
'@esbuild-kit/core-utils': 3.1.0
'@esbuild-kit/esm-loader': 2.5.5
optionalDependencies:
fsevents: 2.3.2
dev: false
/type-check/0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}

View File

@ -563,19 +563,20 @@ export function IsFoot(name: string) {
export function IsExtremities(name: string) {
return ['left_hand', 'right_hand', 'left_foot', 'right_foot'].includes(name)
}
type ControlPartName =
| TupleToUnion<typeof coco_body_keypoints_const>
| 'hip'
| 'shoulder'
| 'five'
| 'right_hand'
| 'left_hand'
| 'left_foot'
| 'right_foot'
| 'torso'
export class BodyControlor {
body: Object3D
part: Record<
| TupleToUnion<typeof coco_body_keypoints_const>
| 'hip'
| 'shoulder'
| 'five'
| 'right_hand'
| 'left_hand'
| 'left_foot'
| 'right_foot',
Object3D
> = {} as any
part: Record<ControlPartName, Object3D> = {} as any
constructor(o: Object3D) {
this.body = o
this.body.traverse((o) => {
@ -592,6 +593,7 @@ export class BodyControlor {
this.part['left_hand'] = this.body.getObjectByName('left_hand')!
this.part['right_foot'] = this.body.getObjectByName('right_foot')!
this.part['left_foot'] = this.body.getObjectByName('left_foot')!
this.part['torso'] = this.body
}
getWorldPosition(o: Object3D) {
@ -599,12 +601,72 @@ export class BodyControlor {
o.getWorldPosition(pos)
return pos
}
UpdateLink(name: ControlPartName) {
switch (name) {
case 'left_hip':
UpdateLink4(
this.part['hip'],
this.part['left_hip'],
'neck',
'left_hip'
)
break
case 'right_hip':
UpdateLink4(
this.part['hip'],
this.part['right_hip'],
'neck',
'right_hip'
)
break
case 'right_shoulder':
UpdateLink4(
this.part['shoulder'],
this.part['right_shoulder'],
'neck',
'right_shoulder'
)
break
case 'left_shoulder':
UpdateLink4(
this.part['shoulder'],
this.part['left_shoulder'],
'neck',
'left_shoulder'
)
break
case 'torso':
break
case 'five':
break
case 'neck':
break
case 'shoulder':
break
case 'right_hand':
break
case 'left_hand':
break
case 'hip':
break
case 'right_foot':
break
case 'left_foot':
break
default:
UpdateLink2(this.part[name].parent!, this.part[name])
break
}
}
get HeadSize() {
const size = this.getWorldPosition(this.part['right_ear']).distanceTo(
this.getWorldPosition(this.part['left_ear'])
)
return size
}
set HeadSize(value: number) {
const scale = value / this.HeadSize
@ -616,17 +678,17 @@ export class BodyControlor {
this.part['left_eye'].position.normalize().multiplyScalar(eyeLength)
this.part['right_eye'].position.normalize().multiplyScalar(eyeLength)
UpdateLink2(this.part['nose'], this.part['left_eye'])
UpdateLink2(this.part['nose'], this.part['right_eye'])
UpdateLink2(this.part['left_eye'], this.part['left_ear'])
UpdateLink2(this.part['right_eye'], this.part['right_ear'])
this.UpdateLink('left_eye')
this.UpdateLink('right_eye')
this.UpdateLink('left_ear')
this.UpdateLink('right_ear')
}
get NoseToNeck() {
return this.part['nose'].position.length()
}
set NoseToNeck(value: number) {
this.part['nose'].position.normalize().multiplyScalar(value)
UpdateLink2(this.part['neck'], this.part['nose'])
this.UpdateLink('nose')
}
get ShoulderToHip() {
return this.part['five'].position.length() * 2
@ -636,13 +698,8 @@ export class BodyControlor {
this.part['left_hip'].position.setY(-value)
this.part['right_hip'].position.setY(-value)
UpdateLink4(this.part['hip'], this.part['left_hip'], 'neck', 'left_hip')
UpdateLink4(
this.part['hip'],
this.part['right_hip'],
'neck',
'right_hip'
)
this.UpdateLink('left_hip')
this.UpdateLink('right_hip')
}
get ShoulderWidth() {
return this.part['left_shoulder'].position.distanceTo(
@ -655,18 +712,8 @@ export class BodyControlor {
const left_shoulder = this.part['left_shoulder']
left_shoulder.position.x = width / 2
UpdateLink4(
this.part['shoulder'],
this.part['right_shoulder'],
'neck',
'right_shoulder'
)
UpdateLink4(
this.part['shoulder'],
this.part['left_shoulder'],
'neck',
'left_shoulder'
)
this.UpdateLink('right_shoulder')
this.UpdateLink('left_shoulder')
}
get UpperArm() {
@ -675,8 +722,8 @@ export class BodyControlor {
set UpperArm(length: number) {
this.part['left_elbow'].position.normalize().multiplyScalar(length)
this.part['right_elbow'].position.normalize().multiplyScalar(length)
UpdateLink2(this.part['left_shoulder'], this.part['left_elbow'])
UpdateLink2(this.part['right_shoulder'], this.part['right_elbow'])
this.UpdateLink('left_elbow')
this.UpdateLink('right_elbow')
}
get Forearm() {
return this.part['left_wrist'].position.length()
@ -685,8 +732,8 @@ export class BodyControlor {
this.part['left_wrist'].position.normalize().multiplyScalar(length)
this.part['right_wrist'].position.normalize().multiplyScalar(length)
UpdateLink2(this.part['left_elbow'], this.part['left_wrist'])
UpdateLink2(this.part['right_elbow'], this.part['right_wrist'])
this.UpdateLink('left_wrist')
this.UpdateLink('right_wrist')
}
get ArmLength() {
@ -705,8 +752,8 @@ export class BodyControlor {
this.part['left_knee'].position.normalize().multiplyScalar(length)
this.part['right_knee'].position.normalize().multiplyScalar(length)
UpdateLink2(this.part['left_hip'], this.part['left_knee'])
UpdateLink2(this.part['right_hip'], this.part['right_knee'])
this.UpdateLink('left_knee')
this.UpdateLink('right_knee')
}
get HandSize() {
@ -728,13 +775,8 @@ export class BodyControlor {
set Hips(width: number) {
this.part['left_hip'].position.setX(width / 2)
this.part['right_hip'].position.setX(-width / 2)
UpdateLink4(this.part['hip'], this.part['left_hip'], 'neck', 'left_hip')
UpdateLink4(
this.part['hip'],
this.part['right_hip'],
'neck',
'right_hip'
)
this.UpdateLink('left_hip')
this.UpdateLink('right_hip')
}
get LowerLeg() {
return this.part['left_ankle'].position.length()
@ -743,8 +785,8 @@ export class BodyControlor {
this.part['left_ankle'].position.normalize().multiplyScalar(length)
this.part['right_ankle'].position.normalize().multiplyScalar(length)
UpdateLink2(this.part['left_knee'], this.part['left_ankle'])
UpdateLink2(this.part['right_knee'], this.part['right_ankle'])
this.UpdateLink('left_ankle')
this.UpdateLink('right_ankle')
}
get LegLength() {
@ -768,4 +810,217 @@ export class BodyControlor {
.divideScalar(origin * FootScale)
.multiplyScalar(size * FootScale)
}
getLocalPosition(obj: Object3D, postion: THREE.Vector3) {
return obj.worldToLocal(postion.clone())
}
getDirectionVectorByParentOf(
name: ControlPartName,
from: THREE.Vector3,
to: THREE.Vector3
) {
const parent = this.part[name].parent!
const localFrom = this.getLocalPosition(parent, from)
const localTo = this.getLocalPosition(parent, to)
return localTo.clone().sub(localFrom).normalize()
}
rotateTo(name: ControlPartName, dir: THREE.Vector3) {
const obj = this.part[name]
const unit = obj.position.clone().normalize()
const axis = unit.clone().cross(dir)
const angle = unit.clone().angleTo(dir)
obj.parent?.setRotationFromAxisAngle(axis.normalize(), angle)
}
setDirectionVector(name: ControlPartName, v: THREE.Vector3) {
const len = this.part[name].position.length()
this.part[name].position.copy(v).multiplyScalar(len)
this.UpdateLink(name)
}
getDistanceOf(from: THREE.Vector3, to: THREE.Vector3) {
return from.distanceTo(to)
}
ResetPose() {
templateBody?.traverse((o) => {
if (o.name in this.part) {
const name = o.name as ControlPartName
this.part[name].position.copy(o.position)
this.part[name].rotation.copy(o.rotation)
this.part[name].scale.copy(o.scale)
this.UpdateLink(name)
}
})
}
SetPose(rawData: [number, number, number][]) {
this.ResetPose()
const data = Object.fromEntries(
Object.entries(PartIndexMappingOfPoseModel).map(([name, index]) => {
return [
name,
new THREE.Vector3().fromArray(rawData[index] ?? [0, 0, 0]),
]
})
) as Record<keyof typeof PartIndexMappingOfPoseModel, THREE.Vector3>
this.part['torso'].position.copy(
data['Hips'].clone().add(data['Chest']).multiplyScalar(0.5)
)
this.Hips = this.getDistanceOf(data['Hips'], data['UpLeg_L']) * 2
this.Thigh = this.getDistanceOf(data['UpLeg_L'], data['Leg_L'])
this.LowerLeg = this.getDistanceOf(data['Leg_L'], data['Foot_L'])
this.UpperArm = this.getDistanceOf(data['Arm_L'], data['ForeArm_L'])
this.Forearm = this.getDistanceOf(data['ForeArm_L'], data['Hand_L'])
this.ShoulderWidth =
2 *
(this.getDistanceOf(data['Shoulder_L'], data['Arm_L']) +
this.getDistanceOf(data['Chest'], data['Shoulder_L']) /
Math.SQRT2)
const map: [
ControlPartName,
[
keyof typeof PartIndexMappingOfPoseModel,
keyof typeof PartIndexMappingOfPoseModel
]
][] = [
['five', ['Hips', 'Chest']],
['left_elbow', ['Arm_L', 'ForeArm_L']],
['left_wrist', ['ForeArm_L', 'Hand_L']],
['left_knee', ['UpLeg_L', 'Leg_L']],
['left_ankle', ['Leg_L', 'Foot_L']],
['right_elbow', ['Arm_R', 'ForeArm_R']],
['right_wrist', ['ForeArm_R', 'Hand_R']],
['right_knee', ['UpLeg_R', 'Leg_R']],
['right_ankle', ['Leg_R', 'Foot_R']],
]
for (const [name, [from, to]] of map)
this.rotateTo(
name,
this.getDirectionVectorByParentOf(name, data[from], data[to])
)
}
}
const PartIndexMappingOfPoseModel = {
Root: 0,
Hips: 1,
Spine: 2,
Spine1: 3,
Spine2: 4,
Chest: 5,
Neck: 6,
Head: 7,
Eye_R: 8,
Eye_L: 9,
Head_Null: 10, // maybe null
Shoulder_L: 11,
Arm_L: 12,
ForeArm_L: 13,
Hand_L: 14,
HandPinky1_L: 15,
HandPinky2_L: 16,
HandPinky3_L: 17,
HandRing1_L: 18,
HandRing2_L: 19,
HandRing3_L: 20,
HandMiddle1_L: 21,
HandMiddle2_L: 22,
HandMiddle3_L: 23,
HandIndex1_L: 24,
HandIndex2_L: 25,
HandIndex3_L: 26,
HandThumb1_L: 27,
HandThumb2_L: 28,
HandThumb3_L: 29,
Elbow_L: 30,
ForeArmTwist_L: 31,
ArmTwist_L: 32,
Shoulder_R: 33,
Arm_R: 34,
ForeArm_R: 35,
Hand_R: 36,
HandPinky1_R: 37,
HandPinky2_R: 38,
HandPinky3_R: 39,
HandRing1_R: 40,
HandRing2_R: 41,
HandRing3_R: 42,
HandMiddle1_R: 43,
HandMiddle2_R: 44,
HandMiddle3_R: 45,
HandIndex1_R: 46,
HandIndex2_R: 47,
HandIndex3_R: 48,
HandThumb1_R: 49,
HandThumb2_R: 50,
HandThumb3_R: 51,
Elbow_R: 52,
ForeArmTwist_R: 53,
ArmTwist_R: 54,
UpLeg_L: 55,
Leg_L: 56,
Knee_L: 57,
Foot_L: 58,
FootPinky1_L: 59,
FootRing_L: 60,
FootMiddle_L: 61,
FootIndex_L: 62,
FootThumb_L: 63,
UpLegTwist_L: 64,
ThighFront_L: 65,
UpLeg_R: 66,
Leg_R: 67,
Knee_R: 68,
Foot_R: 69,
FootPinky1_R: 70,
FootRing_R: 71,
FootMiddle_R: 72,
FootIndex_R: 73,
FootThumb_R: 74,
UpLegTwist_R: 75,
ThighFront_R: 76,
}
const PosesLibraryUrl = new URL('./poses/data.bin', import.meta.url).href
const PosesLibrary: [number, number, number][][] | null = []
function getRandomInt(min: number, max: number) {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}
export function GetRandomPose() {
if (PosesLibrary)
return PosesLibrary[getRandomInt(0, PosesLibrary.length - 1)]
return null
}
export async function LoadPosesLibrary() {
const response = await fetch(PosesLibraryUrl)
const buffer = await response.arrayBuffer()
console.log(buffer.byteLength)
const int16Array = new Int32Array(buffer)
const num = Object.keys(PartIndexMappingOfPoseModel).length
for (let i = 0; i < int16Array.length / (num * 3); i++) {
const temp: [number, number, number][] = []
for (let j = 0; j < num; j++) {
const a = int16Array[i * (num * 3) + j * 3 + 0]
const b = int16Array[i * (num * 3) + j * 3 + 1]
const c = int16Array[i * (num * 3) + j * 3 + 2]
temp.push([a / 1000.0, b / 1000.0, c / 1000.0])
}
PosesLibrary?.push(temp)
}
}

View File

@ -24,6 +24,7 @@ import {
CloneBody,
CreateTemplateBody,
GetExtremityMesh,
GetRandomPose,
IsExtremities,
IsFoot,
IsHand,
@ -31,6 +32,7 @@ import {
IsPickable,
LoadFoot,
LoadHand,
LoadPosesLibrary,
} from './body'
import { options } from './config'
import { SetScreenShot } from './image'
@ -73,6 +75,17 @@ interface CameraData {
type EditorSelectEventHandler = (controlor: BodyControlor) => void
type EditorUnselectEventHandler = () => void
function Oops(error: any) {
Swal.fire({
icon: 'error',
title: i18n.t('Oops...')!,
text: i18n.t('Something went wrong!')! + '\n' + error?.stack ?? error,
footer: `<a href="https://github.com/ZhUyU1997/open-pose-editor/issues">${i18n.t(
'If the problem persists, please click here to ask a question.'
)}</a>`,
})
}
export class BodyEditor {
renderer: THREE.WebGLRenderer
outputRenderer: THREE.WebGLRenderer
@ -837,6 +850,52 @@ export class BodyEditor {
height * window.devicePixelRatio
}
}
async SetRandomPose() {
const bodies = this.scene.children.filter((o) => o.name == 'torso')
const body = bodies.length == 1 ? bodies[0] : this.getSelectedBody()
if (!body) {
await Swal.fire(i18n.t('Please select a skeleton!!'))
return
}
try {
let poseData = GetRandomPose()
if (poseData) {
new BodyControlor(body).SetPose(poseData)
return
}
let loading = true
setTimeout(() => {
if (loading)
Swal.fire({
title: i18n.t('Downloading Poses Library') ?? '',
didOpen: () => {
Swal.showLoading()
},
})
}, 500)
await LoadPosesLibrary()
loading = false
Swal.hideLoading()
Swal.close()
poseData = GetRandomPose()
if (poseData) {
new BodyControlor(body).SetPose(poseData)
return
}
} catch (error) {
Swal.hideLoading()
Swal.close()
Oops(error)
console.error(error)
return
}
}
async loadBodyData() {
const hand = await LoadHand((loaded) => {
@ -1022,16 +1081,7 @@ export class BodyEditor {
if (bodiesObject.length > 0) this.scene.add(...bodiesObject)
this.RestoreCamera(camera)
} catch (error: any) {
Swal.fire({
icon: 'error',
title: i18n.t('Oops...')!,
text:
i18n.t('Something went wrong!')! + '\n' + error?.stack ??
error,
footer: `<a href="https://github.com/ZhUyU1997/open-pose-editor/issues">${i18n.t(
'If the problem persists, please click here to ask a question.'
)}</a>`,
})
Oops(error)
console.error(error)
}
}

View File

@ -37,5 +37,8 @@
"Show Preview": "Show Preview",
"Only Hand": "Only Hand",
"Foot Size": "Foot Size",
"Downloading Foot Model": "Downloading Foot Model"
"Downloading Foot Model": "Downloading Foot Model",
"Please select a skeleton!!": "Please select a skeleton!!",
"Downloading Poses Library": "Downloading Poses Library",
"Set Random Pose [NEW]": "Set Random Pose [NEW]"
}

View File

@ -37,5 +37,8 @@
"Show Preview": "プレビューを表示",
"Only Hand": "手だけ",
"Foot Size": "足のサイズ",
"Downloading Foot Model": "足のモデルをダウンロード中"
"Downloading Foot Model": "足のモデルをダウンロード中",
"Please select a skeleton!!": "骨格を選択してください!",
"Downloading Poses Library": "ポーズライブラリをダウンロード中",
"Set Random Pose [NEW]": "ランダムポーズを設定 [NEW]"
}

View File

@ -37,5 +37,8 @@
"Show Preview": "显示预览图",
"Only Hand": "仅显示手",
"Foot Size": "脚部尺寸",
"Downloading Foot Model": "正在下载脚部模型"
"Downloading Foot Model": "正在下载脚部模型",
"Please select a skeleton!!": "请选择骨架!",
"Downloading Poses Library": "正在下载姿势库",
"Set Random Pose [NEW]": "设置随机姿势 [新]"
}

View File

@ -37,5 +37,8 @@
"Show Preview": "顯示預覽",
"Only Hand": "只顯示手部",
"Foot Size": "腳部尺寸",
"Downloading Foot Model": "正在下載腳部模型"
"Downloading Foot Model": "正在下載腳部模型",
"Please select a skeleton!!": "請選擇骨架!",
"Downloading Poses Library": "下載姿勢庫中",
"Set Random Pose [NEW]": "設定隨機姿勢 [新]"
}

View File

@ -37,5 +37,8 @@
"Show Preview": "顯示預覽",
"Only Hand": "僅手部",
"Foot Size": "腳部大小",
"Downloading Foot Model": "下載腳部模型中"
"Downloading Foot Model": "下載腳部模型中",
"Please select a skeleton!!": "請選擇骨架!",
"Downloading Poses Library": "正在下載姿勢庫",
"Set Random Pose [NEW]": "設置隨機姿勢 [新]"
}

View File

@ -40,6 +40,8 @@ gui.add(editor, 'SaveScene').name(i18n.t('Save Scene'))
gui.add(editor, 'LoadScene').name(i18n.t('Load Scene'))
gui.add(editor, 'RestoreLastSavedScene').name(i18n.t('Restore Last Scene'))
gui.add(editor, 'SetRandomPose').name(i18n.t('Set Random Pose [NEW]'))
options['Width'] = editor.Width
options['Height'] = editor.Height
gui.add(options, 'Width', 128, 5000)

BIN
src/poses/data.bin Normal file

Binary file not shown.

99937
src/poses/data.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ export default defineConfig({
},
plugins: [react(), VitePWA({
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,mp3,obj,fbx}']
globPatterns: ['**/*.{js,css,html,ico,png,svg,mp3,obj,fbx,bin}']
},
manifest: {
name: 'open pose editor',