sa2kit 1.6.60 → 1.6.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/UniversalFileService-C3WQAFOV.js +15 -0
- package/dist/{UniversalFileService-J6ET6KZK.js.map → UniversalFileService-C3WQAFOV.js.map} +1 -1
- package/dist/UniversalFileService-O3IEROBN.mjs +6 -0
- package/dist/{UniversalFileService-336GFY6N.mjs.map → UniversalFileService-O3IEROBN.mjs.map} +1 -1
- package/dist/ai/llm/index.d.mts +70 -0
- package/dist/ai/llm/index.d.ts +70 -0
- package/dist/ai/llm/index.js +54 -0
- package/dist/ai/llm/index.js.map +1 -0
- package/dist/ai/llm/index.mjs +5 -0
- package/dist/ai/llm/index.mjs.map +1 -0
- package/dist/ai/llm/ui/electron/index.d.mts +5 -0
- package/dist/ai/llm/ui/electron/index.d.ts +5 -0
- package/dist/ai/llm/ui/electron/index.js +21 -0
- package/dist/ai/llm/ui/electron/index.js.map +1 -0
- package/dist/ai/llm/ui/electron/index.mjs +8 -0
- package/dist/ai/llm/ui/electron/index.mjs.map +1 -0
- package/dist/ai/llm/ui/miniapp/index.d.mts +9 -0
- package/dist/ai/llm/ui/miniapp/index.d.ts +9 -0
- package/dist/ai/llm/ui/miniapp/index.js +107 -0
- package/dist/ai/llm/ui/miniapp/index.js.map +1 -0
- package/dist/ai/llm/ui/miniapp/index.mjs +101 -0
- package/dist/ai/llm/ui/miniapp/index.mjs.map +1 -0
- package/dist/ai/llm/ui/rn/index.d.mts +9 -0
- package/dist/ai/llm/ui/rn/index.d.ts +9 -0
- package/dist/ai/llm/ui/rn/index.js +249 -0
- package/dist/ai/llm/ui/rn/index.js.map +1 -0
- package/dist/ai/llm/ui/rn/index.mjs +243 -0
- package/dist/ai/llm/ui/rn/index.mjs.map +1 -0
- package/dist/ai/llm/ui/web/index.d.mts +15 -0
- package/dist/ai/llm/ui/web/index.d.ts +15 -0
- package/dist/ai/llm/ui/web/index.js +21 -0
- package/dist/ai/llm/ui/web/index.js.map +1 -0
- package/dist/ai/llm/ui/web/index.mjs +8 -0
- package/dist/ai/llm/ui/web/index.mjs.map +1 -0
- package/dist/ar/index.d.mts +7 -0
- package/dist/ar/index.d.ts +7 -0
- package/dist/ar/index.js +17 -0
- package/dist/ar/index.js.map +1 -0
- package/dist/ar/index.mjs +4 -0
- package/dist/ar/index.mjs.map +1 -0
- package/dist/auth/index.js +22 -22
- package/dist/auth/index.mjs +2 -2
- package/dist/auth/legacy/db/index.d.mts +5 -0
- package/dist/auth/legacy/db/index.d.ts +5 -0
- package/dist/auth/legacy/db/index.js +34 -0
- package/dist/auth/legacy/db/index.js.map +1 -0
- package/dist/auth/legacy/db/index.mjs +5 -0
- package/dist/auth/legacy/db/index.mjs.map +1 -0
- package/dist/auth/legacy/index.d.mts +51 -0
- package/dist/auth/legacy/index.d.ts +51 -0
- package/dist/auth/legacy/index.js +146 -0
- package/dist/auth/legacy/index.js.map +1 -0
- package/dist/auth/legacy/index.mjs +13 -0
- package/dist/auth/legacy/index.mjs.map +1 -0
- package/dist/auth/legacy/logic/index.d.mts +9 -0
- package/dist/auth/legacy/logic/index.d.ts +9 -0
- package/dist/auth/legacy/logic/index.js +18 -0
- package/dist/auth/legacy/logic/index.js.map +1 -0
- package/dist/auth/legacy/logic/index.mjs +5 -0
- package/dist/auth/legacy/logic/index.mjs.map +1 -0
- package/dist/auth/legacy/routes/index.d.mts +50 -0
- package/dist/auth/legacy/routes/index.d.ts +50 -0
- package/dist/auth/legacy/routes/index.js +34 -0
- package/dist/auth/legacy/routes/index.js.map +1 -0
- package/dist/auth/legacy/routes/index.mjs +5 -0
- package/dist/auth/legacy/routes/index.mjs.map +1 -0
- package/dist/auth/legacy/schema/index.d.mts +401 -0
- package/dist/auth/legacy/schema/index.d.ts +401 -0
- package/dist/auth/legacy/schema/index.js +29 -0
- package/dist/auth/legacy/schema/index.js.map +1 -0
- package/dist/auth/legacy/schema/index.mjs +4 -0
- package/dist/auth/legacy/schema/index.mjs.map +1 -0
- package/dist/auth/legacy/server/index.d.mts +15 -0
- package/dist/auth/legacy/server/index.d.ts +15 -0
- package/dist/auth/legacy/server/index.js +65 -0
- package/dist/auth/legacy/server/index.js.map +1 -0
- package/dist/auth/legacy/server/index.mjs +8 -0
- package/dist/auth/legacy/server/index.mjs.map +1 -0
- package/dist/auth/legacy/services/index.d.mts +40 -0
- package/dist/auth/legacy/services/index.d.ts +40 -0
- package/dist/auth/legacy/services/index.js +14 -0
- package/dist/auth/legacy/services/index.js.map +1 -0
- package/dist/auth/legacy/services/index.mjs +5 -0
- package/dist/auth/legacy/services/index.mjs.map +1 -0
- package/dist/auth/legacy/ui/miniapp/index.d.mts +10 -0
- package/dist/auth/legacy/ui/miniapp/index.d.ts +10 -0
- package/dist/auth/legacy/ui/miniapp/index.js +23 -0
- package/dist/auth/legacy/ui/miniapp/index.js.map +1 -0
- package/dist/auth/legacy/ui/miniapp/index.mjs +6 -0
- package/dist/auth/legacy/ui/miniapp/index.mjs.map +1 -0
- package/dist/auth/legacy/ui/web/index.d.mts +22 -0
- package/dist/auth/legacy/ui/web/index.d.ts +22 -0
- package/dist/auth/legacy/ui/web/index.js +31 -0
- package/dist/auth/legacy/ui/web/index.js.map +1 -0
- package/dist/auth/legacy/ui/web/index.mjs +6 -0
- package/dist/auth/legacy/ui/web/index.mjs.map +1 -0
- package/dist/calendar/index.d.mts +390 -237
- package/dist/calendar/index.d.ts +390 -237
- package/dist/calendar/index.js +3825 -3785
- package/dist/calendar/index.js.map +1 -1
- package/dist/calendar/index.mjs +3730 -3696
- package/dist/calendar/index.mjs.map +1 -1
- package/dist/calendar/routes/index.js +30 -327
- package/dist/calendar/routes/index.js.map +1 -1
- package/dist/calendar/routes/index.mjs +1 -323
- package/dist/calendar/routes/index.mjs.map +1 -1
- package/dist/calendar/server.d.mts +6 -0
- package/dist/calendar/server.d.ts +6 -0
- package/dist/calendar/server.js +41 -13
- package/dist/calendar/server.js.map +1 -1
- package/dist/calendar/server.mjs +2 -2
- package/dist/calendar/server.mjs.map +1 -1
- package/dist/chunk-24F7KUED.js +263 -0
- package/dist/chunk-24F7KUED.js.map +1 -0
- package/dist/{chunk-YMS6BPXS.js → chunk-27IUMDDK.js} +3 -3
- package/dist/{chunk-YMS6BPXS.js.map → chunk-27IUMDDK.js.map} +1 -1
- package/dist/chunk-37M6NZIF.js +279 -0
- package/dist/chunk-37M6NZIF.js.map +1 -0
- package/dist/chunk-3JMUNOUT.js +144 -0
- package/dist/chunk-3JMUNOUT.js.map +1 -0
- package/dist/chunk-3PFCOTJP.mjs +256 -0
- package/dist/chunk-3PFCOTJP.mjs.map +1 -0
- package/dist/{chunk-NZZZUMMX.mjs → chunk-57MVE5LL.mjs} +3 -3
- package/dist/{chunk-NZZZUMMX.mjs.map → chunk-57MVE5LL.mjs.map} +1 -1
- package/dist/{chunk-622Y6LTH.mjs → chunk-5BLZEVWK.mjs} +196 -468
- package/dist/chunk-5BLZEVWK.mjs.map +1 -0
- package/dist/{chunk-YN4MJFIG.js → chunk-5LCGOCKG.js} +5 -5
- package/dist/{chunk-YN4MJFIG.js.map → chunk-5LCGOCKG.js.map} +1 -1
- package/dist/chunk-6XUQ2B4K.js +219 -0
- package/dist/chunk-6XUQ2B4K.js.map +1 -0
- package/dist/{chunk-NCOXT7SK.js → chunk-77UEPWVQ.js} +4 -4
- package/dist/{chunk-NCOXT7SK.js.map → chunk-77UEPWVQ.js.map} +1 -1
- package/dist/chunk-CFM56MGO.mjs +35 -0
- package/dist/chunk-CFM56MGO.mjs.map +1 -0
- package/dist/chunk-CPSFYP34.mjs +140 -0
- package/dist/chunk-CPSFYP34.mjs.map +1 -0
- package/dist/chunk-D22QBOCM.mjs +336 -0
- package/dist/chunk-D22QBOCM.mjs.map +1 -0
- package/dist/chunk-DA4QV64P.mjs +35 -0
- package/dist/chunk-DA4QV64P.mjs.map +1 -0
- package/dist/chunk-EKDLZND6.js +275 -0
- package/dist/chunk-EKDLZND6.js.map +1 -0
- package/dist/chunk-EKQPFZXQ.js +12 -0
- package/dist/chunk-EKQPFZXQ.js.map +1 -0
- package/dist/chunk-ERAAB5VG.js +324 -0
- package/dist/chunk-ERAAB5VG.js.map +1 -0
- package/dist/chunk-ESLY72VI.mjs +175 -0
- package/dist/chunk-ESLY72VI.mjs.map +1 -0
- package/dist/chunk-FGQGWW73.js +38 -0
- package/dist/chunk-FGQGWW73.js.map +1 -0
- package/dist/chunk-FXQOXLDE.js +120 -0
- package/dist/chunk-FXQOXLDE.js.map +1 -0
- package/dist/chunk-FZELCJR7.mjs +19 -0
- package/dist/chunk-FZELCJR7.mjs.map +1 -0
- package/dist/{chunk-HHVDOIPV.js → chunk-H3P2PGZL.js} +3 -3
- package/dist/{chunk-HHVDOIPV.js.map → chunk-H3P2PGZL.js.map} +1 -1
- package/dist/chunk-HBQMN5QM.mjs +10 -0
- package/dist/chunk-HBQMN5QM.mjs.map +1 -0
- package/dist/chunk-ITRIXMXF.mjs +862 -0
- package/dist/chunk-ITRIXMXF.mjs.map +1 -0
- package/dist/chunk-IUWSCUDC.js +4 -0
- package/dist/chunk-IUWSCUDC.js.map +1 -0
- package/dist/chunk-JCKCKRC2.js +50 -0
- package/dist/chunk-JCKCKRC2.js.map +1 -0
- package/dist/chunk-L7GQNY54.mjs +286 -0
- package/dist/chunk-L7GQNY54.mjs.map +1 -0
- package/dist/{chunk-ZRWED7Q6.js → chunk-LDVJ7URJ.js} +235 -520
- package/dist/chunk-LDVJ7URJ.js.map +1 -0
- package/dist/{chunk-CYTXGBP2.js → chunk-MLP74E3O.js} +573 -1607
- package/dist/chunk-MLP74E3O.js.map +1 -0
- package/dist/chunk-NAX4TUT7.js +182 -0
- package/dist/chunk-NAX4TUT7.js.map +1 -0
- package/dist/chunk-NW4EN4YI.mjs +213 -0
- package/dist/chunk-NW4EN4YI.mjs.map +1 -0
- package/dist/chunk-P3QMT3AY.mjs +44 -0
- package/dist/chunk-P3QMT3AY.mjs.map +1 -0
- package/dist/chunk-PJ4KYAQZ.mjs +631 -0
- package/dist/chunk-PJ4KYAQZ.mjs.map +1 -0
- package/dist/chunk-PLSEAREM.js +345 -0
- package/dist/chunk-PLSEAREM.js.map +1 -0
- package/dist/{chunk-EGJPS7OL.mjs → chunk-QZU4UJZG.mjs} +3 -3
- package/dist/{chunk-EGJPS7OL.mjs.map → chunk-QZU4UJZG.mjs.map} +1 -1
- package/dist/chunk-RJVR33ME.mjs +3 -0
- package/dist/chunk-RJVR33ME.mjs.map +1 -0
- package/dist/chunk-SYBHDB2D.js +650 -0
- package/dist/chunk-SYBHDB2D.js.map +1 -0
- package/dist/chunk-TVKVM7JT.js +21 -0
- package/dist/chunk-TVKVM7JT.js.map +1 -0
- package/dist/{chunk-PONZPO3U.mjs → chunk-UTB72ZJ7.mjs} +414 -1448
- package/dist/chunk-UTB72ZJ7.mjs.map +1 -0
- package/dist/chunk-V7EVKD5G.mjs +116 -0
- package/dist/chunk-V7EVKD5G.mjs.map +1 -0
- package/dist/chunk-VGPR3KLR.js +872 -0
- package/dist/chunk-VGPR3KLR.js.map +1 -0
- package/dist/chunk-VS7WATQD.js +255 -0
- package/dist/chunk-VS7WATQD.js.map +1 -0
- package/dist/chunk-VSP7XJT5.mjs +272 -0
- package/dist/chunk-VSP7XJT5.mjs.map +1 -0
- package/dist/{chunk-CSDIPQQO.mjs → chunk-VTKAIOP5.mjs} +5 -5
- package/dist/{chunk-CSDIPQQO.mjs.map → chunk-VTKAIOP5.mjs.map} +1 -1
- package/dist/chunk-VULJUXTF.mjs +267 -0
- package/dist/chunk-VULJUXTF.mjs.map +1 -0
- package/dist/chunk-XAHM6B3V.js +44 -0
- package/dist/chunk-XAHM6B3V.js.map +1 -0
- package/dist/chunk-YSF5YISM.mjs +248 -0
- package/dist/chunk-YSF5YISM.mjs.map +1 -0
- package/dist/{chunk-OFYBMMWT.mjs → chunk-YYJEVAJI.mjs} +3 -3
- package/dist/{chunk-OFYBMMWT.mjs.map → chunk-YYJEVAJI.mjs.map} +1 -1
- package/dist/components/index.d.mts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +182 -181
- package/dist/components/index.mjs +4 -3
- package/dist/index-DNKZ7-R_.d.mts +184 -0
- package/dist/index-DNKZ7-R_.d.ts +184 -0
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +285 -229
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -10
- package/dist/index.mjs.map +1 -1
- package/dist/mikuFusionGame/index.js +3 -3
- package/dist/mikuFusionGame/index.mjs +2 -2
- package/dist/mmd/index.d.mts +67 -9
- package/dist/mmd/index.d.ts +67 -9
- package/dist/mmd/index.js +969 -625
- package/dist/mmd/index.js.map +1 -1
- package/dist/mmd/index.mjs +969 -628
- package/dist/mmd/index.mjs.map +1 -1
- package/dist/portfolio/index.js +10 -9
- package/dist/portfolio/index.mjs +5 -4
- package/dist/qqbot/index.d.mts +2 -0
- package/dist/qqbot/index.d.ts +2 -0
- package/dist/qqbot/index.js +21 -0
- package/dist/qqbot/index.js.map +1 -0
- package/dist/qqbot/index.mjs +4 -0
- package/dist/qqbot/index.mjs.map +1 -0
- package/dist/qqbot/server/index.d.mts +91 -0
- package/dist/qqbot/server/index.d.ts +91 -0
- package/dist/qqbot/server/index.js +21 -0
- package/dist/qqbot/server/index.js.map +1 -0
- package/dist/qqbot/server/index.mjs +4 -0
- package/dist/qqbot/server/index.mjs.map +1 -0
- package/dist/qqbot/ui/web/index.d.mts +10 -0
- package/dist/qqbot/ui/web/index.d.ts +10 -0
- package/dist/qqbot/ui/web/index.js +105 -0
- package/dist/qqbot/ui/web/index.js.map +1 -0
- package/dist/qqbot/ui/web/index.mjs +99 -0
- package/dist/qqbot/ui/web/index.mjs.map +1 -0
- package/dist/screenReceiver/index.d.mts +78 -0
- package/dist/screenReceiver/index.d.ts +78 -0
- package/dist/screenReceiver/index.js +17 -0
- package/dist/screenReceiver/index.js.map +1 -0
- package/dist/screenReceiver/index.mjs +4 -0
- package/dist/screenReceiver/index.mjs.map +1 -0
- package/dist/screenReceiver/server/index.d.mts +36 -0
- package/dist/screenReceiver/server/index.d.ts +36 -0
- package/dist/screenReceiver/server/index.js +160 -0
- package/dist/screenReceiver/server/index.js.map +1 -0
- package/dist/screenReceiver/server/index.mjs +157 -0
- package/dist/screenReceiver/server/index.mjs.map +1 -0
- package/dist/showmasterpiece/db/index.js +42 -42
- package/dist/showmasterpiece/db/index.mjs +1 -1
- package/dist/showmasterpiece/index.js +52 -41
- package/dist/showmasterpiece/index.js.map +1 -1
- package/dist/showmasterpiece/index.mjs +15 -4
- package/dist/showmasterpiece/index.mjs.map +1 -1
- package/dist/showmasterpiece/server/index.js +42 -42
- package/dist/showmasterpiece/server/index.mjs +1 -1
- package/dist/showmasterpiece/ui/miniapp/index.d.mts +2 -0
- package/dist/showmasterpiece/ui/miniapp/index.d.ts +2 -0
- package/dist/showmasterpiece/ui/miniapp/index.js +83 -55
- package/dist/showmasterpiece/ui/miniapp/index.js.map +1 -1
- package/dist/showmasterpiece/ui/miniapp/index.mjs +83 -55
- package/dist/showmasterpiece/ui/miniapp/index.mjs.map +1 -1
- package/dist/showmasterpiece/ui/web/index.js +43 -32
- package/dist/showmasterpiece/ui/web/index.mjs +15 -4
- package/dist/testYourself/index.js +13 -13
- package/dist/testYourself/index.mjs +2 -2
- package/dist/types-B-hOccQw.d.mts +122 -0
- package/dist/types-B8rGXc4e.d.mts +38 -0
- package/dist/types-Cg89HGz2.d.ts +38 -0
- package/dist/types-CvKvpyN8.d.mts +48 -0
- package/dist/types-CvKvpyN8.d.ts +48 -0
- package/dist/types-Dy6x2gJW.d.ts +122 -0
- package/dist/universalFile/server/index.js +11 -11
- package/dist/universalFile/server/index.mjs +4 -4
- package/package.json +101 -1
- package/dist/UniversalFileService-336GFY6N.mjs +0 -6
- package/dist/UniversalFileService-J6ET6KZK.js +0 -15
- package/dist/chunk-622Y6LTH.mjs.map +0 -1
- package/dist/chunk-CYTXGBP2.js.map +0 -1
- package/dist/chunk-GVVS4IMM.mjs +0 -302
- package/dist/chunk-GVVS4IMM.mjs.map +0 -1
- package/dist/chunk-PONZPO3U.mjs.map +0 -1
- package/dist/chunk-WC5QFO3T.js +0 -314
- package/dist/chunk-WC5QFO3T.js.map +0 -1
- package/dist/chunk-ZRWED7Q6.js.map +0 -1
package/dist/mmd/index.js
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
var chunkUIFFDRTE_js = require('../chunk-UIFFDRTE.js');
|
|
4
4
|
var chunkTDCDEBGP_js = require('../chunk-TDCDEBGP.js');
|
|
5
5
|
require('../chunk-WA67GZSZ.js');
|
|
6
|
+
var chunkFGQGWW73_js = require('../chunk-FGQGWW73.js');
|
|
6
7
|
require('../chunk-Z6ZWNWWR.js');
|
|
7
8
|
var React10 = require('react');
|
|
8
9
|
var clsx = require('clsx');
|
|
9
10
|
var THREE2 = require('three');
|
|
10
11
|
var threeStdlib = require('three-stdlib');
|
|
11
12
|
var lucideReact = require('lucide-react');
|
|
13
|
+
var JSZip = require('jszip');
|
|
12
14
|
var reactDom = require('react-dom');
|
|
13
|
-
var Script = require('next/script');
|
|
14
15
|
|
|
15
16
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
17
|
|
|
@@ -34,7 +35,7 @@ function _interopNamespace(e) {
|
|
|
34
35
|
|
|
35
36
|
var React10__default = /*#__PURE__*/_interopDefault(React10);
|
|
36
37
|
var THREE2__namespace = /*#__PURE__*/_interopNamespace(THREE2);
|
|
37
|
-
var
|
|
38
|
+
var JSZip__default = /*#__PURE__*/_interopDefault(JSZip);
|
|
38
39
|
|
|
39
40
|
// src/mmd/pmx/editor/PMXEditor.ts
|
|
40
41
|
var PMXEditor = class {
|
|
@@ -3438,6 +3439,188 @@ var MMDLightingDebugPanel = ({
|
|
|
3438
3439
|
));
|
|
3439
3440
|
};
|
|
3440
3441
|
MMDLightingDebugPanel.displayName = "MMDLightingDebugPanel";
|
|
3442
|
+
var MMD_UPLOAD_CONFIGS = {
|
|
3443
|
+
model: {
|
|
3444
|
+
moduleId: "mmd-models",
|
|
3445
|
+
acceptedTypes: [".zip"],
|
|
3446
|
+
maxFileSize: 150,
|
|
3447
|
+
description: "MMD model package (ZIP)",
|
|
3448
|
+
hint: "Include PMX/PMD and textures in the ZIP with original folder structure."
|
|
3449
|
+
},
|
|
3450
|
+
motion: {
|
|
3451
|
+
moduleId: "mmd-motions",
|
|
3452
|
+
acceptedTypes: [".vmd"],
|
|
3453
|
+
maxFileSize: 20,
|
|
3454
|
+
description: "MMD motion file"
|
|
3455
|
+
},
|
|
3456
|
+
camera: {
|
|
3457
|
+
moduleId: "mmd-cameras",
|
|
3458
|
+
acceptedTypes: [".vmd"],
|
|
3459
|
+
maxFileSize: 10,
|
|
3460
|
+
description: "MMD camera motion"
|
|
3461
|
+
},
|
|
3462
|
+
audio: {
|
|
3463
|
+
moduleId: "mmd-audios",
|
|
3464
|
+
acceptedTypes: [".mp3", ".wav", ".ogg", ".m4a"],
|
|
3465
|
+
maxFileSize: 20,
|
|
3466
|
+
description: "Audio track"
|
|
3467
|
+
},
|
|
3468
|
+
stage: {
|
|
3469
|
+
moduleId: "mmd-stages",
|
|
3470
|
+
acceptedTypes: [".zip"],
|
|
3471
|
+
maxFileSize: 200,
|
|
3472
|
+
description: "Stage package (ZIP)",
|
|
3473
|
+
hint: "Include stage model and textures in the ZIP with original folder structure."
|
|
3474
|
+
},
|
|
3475
|
+
thumbnail: {
|
|
3476
|
+
moduleId: "mmd-thumbnails",
|
|
3477
|
+
acceptedTypes: [".jpg", ".jpeg", ".png", ".webp"],
|
|
3478
|
+
maxFileSize: 5,
|
|
3479
|
+
description: "Thumbnail image"
|
|
3480
|
+
}
|
|
3481
|
+
};
|
|
3482
|
+
var formatMegabytes = (size) => `${(size / 1024 / 1024).toFixed(2)} MB`;
|
|
3483
|
+
var MMDUploadPanel = ({
|
|
3484
|
+
resourceType,
|
|
3485
|
+
fileService,
|
|
3486
|
+
userId,
|
|
3487
|
+
permission = "public",
|
|
3488
|
+
label,
|
|
3489
|
+
description,
|
|
3490
|
+
hint,
|
|
3491
|
+
acceptedTypes,
|
|
3492
|
+
maxFileSizeMB,
|
|
3493
|
+
validateZip = true,
|
|
3494
|
+
disabled = false,
|
|
3495
|
+
className,
|
|
3496
|
+
style,
|
|
3497
|
+
onUploaded,
|
|
3498
|
+
onError,
|
|
3499
|
+
onProgress
|
|
3500
|
+
}) => {
|
|
3501
|
+
const inputId = React10.useId();
|
|
3502
|
+
const [uploading, setUploading] = React10.useState(false);
|
|
3503
|
+
const [progress, setProgress] = React10.useState(null);
|
|
3504
|
+
const [error, setError] = React10.useState(null);
|
|
3505
|
+
const [uploadedFile, setUploadedFile] = React10.useState(null);
|
|
3506
|
+
const [uploadedUrl, setUploadedUrl] = React10.useState(null);
|
|
3507
|
+
const [dragOver, setDragOver] = React10.useState(false);
|
|
3508
|
+
const config = MMD_UPLOAD_CONFIGS[resourceType];
|
|
3509
|
+
const mergedAcceptedTypes = acceptedTypes ?? config.acceptedTypes;
|
|
3510
|
+
const maxSize = maxFileSizeMB ?? config.maxFileSize;
|
|
3511
|
+
const hintText = hint ?? config.hint;
|
|
3512
|
+
const titleText = label ?? config.description;
|
|
3513
|
+
const descriptionText = description ?? `Max ${maxSize} MB`;
|
|
3514
|
+
const acceptAttr = React10.useMemo(() => mergedAcceptedTypes.join(","), [mergedAcceptedTypes]);
|
|
3515
|
+
const validateZipContents = async (file) => {
|
|
3516
|
+
if (!validateZip || !(resourceType === "model" || resourceType === "stage")) return;
|
|
3517
|
+
const buffer = await file.arrayBuffer();
|
|
3518
|
+
const zip = await JSZip__default.default.loadAsync(buffer);
|
|
3519
|
+
const entries = Object.keys(zip.files);
|
|
3520
|
+
if (!entries.length) {
|
|
3521
|
+
throw new Error("ZIP is empty.");
|
|
3522
|
+
}
|
|
3523
|
+
const hasModel = entries.some((name) => /\.[pP][mM][xX]$/.test(name)) || resourceType === "stage" && entries.some((name) => /\.[pP][mM][dD]$/.test(name));
|
|
3524
|
+
const hasAssets = entries.some(
|
|
3525
|
+
(name) => /\.(png|jpg|jpeg|bmp|tga|dds|spa|sph)$/i.test(name)
|
|
3526
|
+
);
|
|
3527
|
+
if (!hasModel) {
|
|
3528
|
+
throw new Error("ZIP does not contain a PMX/PMD model file.");
|
|
3529
|
+
}
|
|
3530
|
+
if (!hasAssets) {
|
|
3531
|
+
throw new Error("ZIP does not include texture assets.");
|
|
3532
|
+
}
|
|
3533
|
+
};
|
|
3534
|
+
const handleUpload = async (file) => {
|
|
3535
|
+
if (disabled || uploading) return;
|
|
3536
|
+
setError(null);
|
|
3537
|
+
setProgress(null);
|
|
3538
|
+
if (file.size > maxSize * 1024 * 1024) {
|
|
3539
|
+
setError(`File size exceeds ${maxSize} MB.`);
|
|
3540
|
+
return;
|
|
3541
|
+
}
|
|
3542
|
+
try {
|
|
3543
|
+
setUploading(true);
|
|
3544
|
+
await validateZipContents(file);
|
|
3545
|
+
const fileInfo = {
|
|
3546
|
+
file,
|
|
3547
|
+
moduleId: config.moduleId,
|
|
3548
|
+
businessId: userId,
|
|
3549
|
+
permission
|
|
3550
|
+
};
|
|
3551
|
+
const metadata = await fileService.uploadFile(fileInfo, (progressEvent) => {
|
|
3552
|
+
setProgress(progressEvent);
|
|
3553
|
+
onProgress?.(progressEvent);
|
|
3554
|
+
});
|
|
3555
|
+
let url;
|
|
3556
|
+
if (fileService.getFileUrl) {
|
|
3557
|
+
url = await fileService.getFileUrl(metadata.id);
|
|
3558
|
+
setUploadedUrl(url ?? null);
|
|
3559
|
+
} else {
|
|
3560
|
+
setUploadedUrl(null);
|
|
3561
|
+
}
|
|
3562
|
+
setUploadedFile(metadata);
|
|
3563
|
+
setUploading(false);
|
|
3564
|
+
onUploaded?.({ file: metadata, url });
|
|
3565
|
+
} catch (err) {
|
|
3566
|
+
const message = err instanceof Error ? err.message : "Upload failed.";
|
|
3567
|
+
setError(message);
|
|
3568
|
+
setUploading(false);
|
|
3569
|
+
onError?.(err instanceof Error ? err : new Error(message));
|
|
3570
|
+
}
|
|
3571
|
+
};
|
|
3572
|
+
const handleFileInput = (event) => {
|
|
3573
|
+
const file = event.target.files?.[0];
|
|
3574
|
+
if (file) {
|
|
3575
|
+
handleUpload(file);
|
|
3576
|
+
}
|
|
3577
|
+
};
|
|
3578
|
+
const handleDrop = (event) => {
|
|
3579
|
+
event.preventDefault();
|
|
3580
|
+
setDragOver(false);
|
|
3581
|
+
const file = event.dataTransfer.files?.[0];
|
|
3582
|
+
if (file) {
|
|
3583
|
+
handleUpload(file);
|
|
3584
|
+
}
|
|
3585
|
+
};
|
|
3586
|
+
return /* @__PURE__ */ React10__default.default.createElement("div", { className: clsx.clsx("space-y-4", className), style }, /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-sm font-semibold text-gray-900" }, titleText), /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-xs text-gray-500" }, descriptionText), hintText && /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-xs text-amber-600 mt-1" }, hintText)), /* @__PURE__ */ React10__default.default.createElement(
|
|
3587
|
+
"div",
|
|
3588
|
+
{
|
|
3589
|
+
className: clsx.clsx(
|
|
3590
|
+
"rounded-lg border-2 border-dashed px-4 py-6 text-center transition-colors",
|
|
3591
|
+
dragOver ? "border-blue-500 bg-blue-50" : "border-gray-300",
|
|
3592
|
+
disabled ? "opacity-50 pointer-events-none" : "cursor-pointer"
|
|
3593
|
+
),
|
|
3594
|
+
onDragOver: (event) => {
|
|
3595
|
+
event.preventDefault();
|
|
3596
|
+
setDragOver(true);
|
|
3597
|
+
},
|
|
3598
|
+
onDragLeave: () => setDragOver(false),
|
|
3599
|
+
onDrop: handleDrop
|
|
3600
|
+
},
|
|
3601
|
+
/* @__PURE__ */ React10__default.default.createElement(
|
|
3602
|
+
"input",
|
|
3603
|
+
{
|
|
3604
|
+
id: inputId,
|
|
3605
|
+
type: "file",
|
|
3606
|
+
accept: acceptAttr,
|
|
3607
|
+
className: "hidden",
|
|
3608
|
+
onChange: handleFileInput,
|
|
3609
|
+
disabled: disabled || uploading
|
|
3610
|
+
}
|
|
3611
|
+
),
|
|
3612
|
+
/* @__PURE__ */ React10__default.default.createElement("label", { htmlFor: inputId, className: "flex flex-col items-center gap-2" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Upload, { className: "h-6 w-6 text-gray-500" }), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-sm text-gray-600" }, "Click to select or drag file here"), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-xs text-gray-400" }, mergedAcceptedTypes.join(", ")))
|
|
3613
|
+
), uploading && /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center gap-2 text-sm text-blue-600" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }), "Uploading", progress ? ` ${progress.progress}%` : "..."), progress && /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-xs text-gray-500" }, formatMegabytes(progress.uploadedBytes), " / ", formatMegabytes(progress.totalBytes)), error && /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-sm text-red-600" }, error), uploadedFile && /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center justify-between rounded-lg border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React10__default.default.createElement(lucideReact.CheckCircle2, { className: "h-4 w-4" }), /* @__PURE__ */ React10__default.default.createElement("span", { className: "truncate" }, uploadedFile.originalName)), uploadedUrl && /* @__PURE__ */ React10__default.default.createElement(
|
|
3614
|
+
"a",
|
|
3615
|
+
{
|
|
3616
|
+
href: uploadedUrl,
|
|
3617
|
+
target: "_blank",
|
|
3618
|
+
rel: "noreferrer",
|
|
3619
|
+
className: "text-green-700 underline"
|
|
3620
|
+
},
|
|
3621
|
+
"Open"
|
|
3622
|
+
)));
|
|
3623
|
+
};
|
|
3441
3624
|
function diagnoseMaterialsMMD(scene, renderer) {
|
|
3442
3625
|
const report = {
|
|
3443
3626
|
totalMaterials: 0,
|
|
@@ -5089,6 +5272,8 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5089
5272
|
onScriptComplete,
|
|
5090
5273
|
onError,
|
|
5091
5274
|
showDebugInfo = false,
|
|
5275
|
+
debug = false,
|
|
5276
|
+
onTransitionStateChange,
|
|
5092
5277
|
showSkipButton = true,
|
|
5093
5278
|
showAutoButton = true,
|
|
5094
5279
|
showHistoryButton = true,
|
|
@@ -5128,6 +5313,26 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5128
5313
|
const cheerParticlesRef = React10.useRef(null);
|
|
5129
5314
|
const currentNode = nodes[currentNodeIndex];
|
|
5130
5315
|
const currentDialogue = currentNode?.dialogues[currentDialogueIndex] || null;
|
|
5316
|
+
const log = React10.useCallback((...args) => {
|
|
5317
|
+
if (!debug) return;
|
|
5318
|
+
console.log("[MMDVisualNovel]", ...args);
|
|
5319
|
+
}, [debug]);
|
|
5320
|
+
React10.useEffect(() => {
|
|
5321
|
+
if (!onTransitionStateChange) return;
|
|
5322
|
+
if (!isStarted) {
|
|
5323
|
+
onTransitionStateChange("idle");
|
|
5324
|
+
return;
|
|
5325
|
+
}
|
|
5326
|
+
if (isTransitioning) {
|
|
5327
|
+
onTransitionStateChange("transitioning");
|
|
5328
|
+
return;
|
|
5329
|
+
}
|
|
5330
|
+
if (isLoading || !isAnimationPlaying) {
|
|
5331
|
+
onTransitionStateChange("loading");
|
|
5332
|
+
return;
|
|
5333
|
+
}
|
|
5334
|
+
onTransitionStateChange("ready");
|
|
5335
|
+
}, [isStarted, isTransitioning, isLoading, isAnimationPlaying, onTransitionStateChange]);
|
|
5131
5336
|
const addToHistory = React10.useCallback((dialogue, nodeIndex, dialogueIndex) => {
|
|
5132
5337
|
setHistory((prev) => [
|
|
5133
5338
|
...prev,
|
|
@@ -5159,11 +5364,11 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5159
5364
|
if (!node) return;
|
|
5160
5365
|
const currentResources = nodes[currentNodeIndex]?.resources;
|
|
5161
5366
|
if (!force && currentResources?.motionPath && !isVmdFinishedRef.current) {
|
|
5162
|
-
|
|
5367
|
+
log("VMD not finished, showing confirmation");
|
|
5163
5368
|
setPendingNodeIndex(nodeIndex);
|
|
5164
5369
|
return;
|
|
5165
5370
|
}
|
|
5166
|
-
|
|
5371
|
+
log("Transitioning to node", nodeIndex);
|
|
5167
5372
|
setIsTransitioning(true);
|
|
5168
5373
|
setIsLoading(true);
|
|
5169
5374
|
setIsAnimationPlaying(false);
|
|
@@ -5185,7 +5390,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5185
5390
|
}
|
|
5186
5391
|
setTimeout(() => {
|
|
5187
5392
|
setIsTransitioning(false);
|
|
5188
|
-
|
|
5393
|
+
log("Transition to node completed, waiting for model load", nodeIndex);
|
|
5189
5394
|
}, 100);
|
|
5190
5395
|
}, 300);
|
|
5191
5396
|
},
|
|
@@ -5199,7 +5404,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5199
5404
|
const val = variables[key];
|
|
5200
5405
|
if (val !== void 0 && map[val] !== void 0) {
|
|
5201
5406
|
nextNodeIndex = map[val];
|
|
5202
|
-
|
|
5407
|
+
log("Branching", { key, val, nextNodeIndex });
|
|
5203
5408
|
} else {
|
|
5204
5409
|
nextNodeIndex = defaultIndex;
|
|
5205
5410
|
}
|
|
@@ -5207,7 +5412,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5207
5412
|
if (nextNodeIndex < nodes.length && nextNodeIndex >= 0) {
|
|
5208
5413
|
goToNode(nextNodeIndex);
|
|
5209
5414
|
} else if (loop) {
|
|
5210
|
-
|
|
5415
|
+
log("Reached final node, showing loop confirmation");
|
|
5211
5416
|
setShowLoopConfirm(true);
|
|
5212
5417
|
} else {
|
|
5213
5418
|
onScriptComplete?.();
|
|
@@ -5299,7 +5504,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5299
5504
|
if (nextNodeIndex < nodes.length) {
|
|
5300
5505
|
goToNode(nextNodeIndex);
|
|
5301
5506
|
} else if (loop) {
|
|
5302
|
-
|
|
5507
|
+
log("Skip reached final node, showing loop confirmation");
|
|
5303
5508
|
setShowLoopConfirm(true);
|
|
5304
5509
|
} else {
|
|
5305
5510
|
onScriptComplete?.();
|
|
@@ -5326,16 +5531,16 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5326
5531
|
setIsLoading(true);
|
|
5327
5532
|
setIsAnimationPlaying(false);
|
|
5328
5533
|
typingCompleteRef.current = false;
|
|
5329
|
-
|
|
5534
|
+
log("Back to start screen");
|
|
5330
5535
|
}, [initialNodeIndex, initialDialogueIndex]);
|
|
5331
5536
|
const handleCheer = React10.useCallback(() => {
|
|
5332
|
-
|
|
5537
|
+
log("Trigger cheer effect");
|
|
5333
5538
|
cheerParticlesRef.current?.trigger();
|
|
5334
5539
|
}, []);
|
|
5335
5540
|
const handleRestartLoop = React10.useCallback(() => {
|
|
5336
5541
|
setShowLoopConfirm(false);
|
|
5337
5542
|
goToNode(0, true);
|
|
5338
|
-
|
|
5543
|
+
log("Restart loop");
|
|
5339
5544
|
}, [goToNode]);
|
|
5340
5545
|
React10.useImperativeHandle(
|
|
5341
5546
|
ref,
|
|
@@ -5404,17 +5609,17 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5404
5609
|
loop: currentNode.loopAnimation === true,
|
|
5405
5610
|
mobileOptimization,
|
|
5406
5611
|
onLoad: () => {
|
|
5407
|
-
|
|
5612
|
+
log("MMDPlayerBase onLoad");
|
|
5408
5613
|
setIsLoading(false);
|
|
5409
5614
|
if (isStartedRef.current) {
|
|
5410
|
-
|
|
5615
|
+
log("Game already started, triggering play");
|
|
5411
5616
|
setTimeout(() => {
|
|
5412
5617
|
playerRef.current?.play();
|
|
5413
5618
|
}, 100);
|
|
5414
5619
|
}
|
|
5415
5620
|
},
|
|
5416
5621
|
onPlay: () => {
|
|
5417
|
-
|
|
5622
|
+
log("MMDPlayerBase onPlay");
|
|
5418
5623
|
setIsAnimationPlaying(true);
|
|
5419
5624
|
},
|
|
5420
5625
|
onTimeUpdate: (time) => {
|
|
@@ -5423,7 +5628,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5423
5628
|
const isLooped = time < lastAnimationTimeRef.current && lastAnimationTimeRef.current > 0;
|
|
5424
5629
|
if (isNearEnd || isLooped) {
|
|
5425
5630
|
if (!isVmdFinishedRef.current) {
|
|
5426
|
-
|
|
5631
|
+
log("VMD finished/looped, marking as finished");
|
|
5427
5632
|
isVmdFinishedRef.current = true;
|
|
5428
5633
|
setIsVmdFinished(true);
|
|
5429
5634
|
}
|
|
@@ -5431,7 +5636,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5431
5636
|
lastAnimationTimeRef.current = time;
|
|
5432
5637
|
},
|
|
5433
5638
|
onEnded: () => {
|
|
5434
|
-
|
|
5639
|
+
log("VMD ended, marking as finished");
|
|
5435
5640
|
isVmdFinishedRef.current = true;
|
|
5436
5641
|
setIsVmdFinished(true);
|
|
5437
5642
|
},
|
|
@@ -5477,17 +5682,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5477
5682
|
/* @__PURE__ */ React10__default.default.createElement(
|
|
5478
5683
|
LoadingOverlay,
|
|
5479
5684
|
{
|
|
5480
|
-
isLoading: (
|
|
5481
|
-
const shouldShowLoading = (isLoading || isTransitioning || !isAnimationPlaying) && isStarted;
|
|
5482
|
-
console.log("[MMDVisualNovel] LoadingOverlay conditions:", {
|
|
5483
|
-
isLoading,
|
|
5484
|
-
isTransitioning,
|
|
5485
|
-
isAnimationPlaying,
|
|
5486
|
-
isStarted,
|
|
5487
|
-
shouldShowLoading
|
|
5488
|
-
});
|
|
5489
|
-
return shouldShowLoading;
|
|
5490
|
-
})(),
|
|
5685
|
+
isLoading: (isLoading || isTransitioning || !isAnimationPlaying) && isStarted,
|
|
5491
5686
|
showStartScreen: !isStarted,
|
|
5492
5687
|
scriptName: script.name,
|
|
5493
5688
|
loadingText: "\u6B63\u5728\u51C6\u5907\u573A\u666F\u4E2D...",
|
|
@@ -5499,44 +5694,31 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5499
5694
|
customAboutContent
|
|
5500
5695
|
}
|
|
5501
5696
|
),
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
{
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
onSkip: handleSkip,
|
|
5528
|
-
onResetCamera: () => {
|
|
5529
|
-
playerRef.current?.resetCamera();
|
|
5530
|
-
setIsCameraManual(false);
|
|
5531
|
-
},
|
|
5532
|
-
isCameraManual,
|
|
5533
|
-
showControls: true,
|
|
5534
|
-
showSkipButton,
|
|
5535
|
-
showAutoButton,
|
|
5536
|
-
showHistoryButton
|
|
5537
|
-
}
|
|
5538
|
-
) : null;
|
|
5539
|
-
})(),
|
|
5697
|
+
isStarted && isAnimationPlaying && currentDialogue && !showHistory && !showChoices && !showLoopConfirm ? /* @__PURE__ */ React10__default.default.createElement(
|
|
5698
|
+
DialogueBox,
|
|
5699
|
+
{
|
|
5700
|
+
dialogue: currentDialogue,
|
|
5701
|
+
theme: dialogueTheme,
|
|
5702
|
+
isTyping,
|
|
5703
|
+
isAutoMode,
|
|
5704
|
+
onClick: handleDialogueClick,
|
|
5705
|
+
onSkipTyping: () => {
|
|
5706
|
+
typingCompleteRef.current = true;
|
|
5707
|
+
},
|
|
5708
|
+
onToggleAuto: toggleAutoMode,
|
|
5709
|
+
onOpenHistory: () => setShowHistory(true),
|
|
5710
|
+
onSkip: handleSkip,
|
|
5711
|
+
onResetCamera: () => {
|
|
5712
|
+
playerRef.current?.resetCamera();
|
|
5713
|
+
setIsCameraManual(false);
|
|
5714
|
+
},
|
|
5715
|
+
isCameraManual,
|
|
5716
|
+
showControls: true,
|
|
5717
|
+
showSkipButton,
|
|
5718
|
+
showAutoButton,
|
|
5719
|
+
showHistoryButton
|
|
5720
|
+
}
|
|
5721
|
+
) : null,
|
|
5540
5722
|
pendingNodeIndex !== null && /* @__PURE__ */ React10__default.default.createElement(
|
|
5541
5723
|
SkipConfirmDialog,
|
|
5542
5724
|
{
|
|
@@ -5559,7 +5741,7 @@ var MMDVisualNovel = React10.forwardRef(
|
|
|
5559
5741
|
if (choice.setVariable) {
|
|
5560
5742
|
const { key, value } = choice.setVariable;
|
|
5561
5743
|
setVariables((prev) => ({ ...prev, [key]: value }));
|
|
5562
|
-
|
|
5744
|
+
log("Variable set", { key, value });
|
|
5563
5745
|
}
|
|
5564
5746
|
choice.onSelect?.();
|
|
5565
5747
|
if (choice.effect) {
|
|
@@ -5701,6 +5883,7 @@ var MMDVisualNovelWithSelector = React10.forwardRef((props, ref) => {
|
|
|
5701
5883
|
script,
|
|
5702
5884
|
modelSelector,
|
|
5703
5885
|
onModelSelectionChange,
|
|
5886
|
+
resourceMappingMode = "resource-map",
|
|
5704
5887
|
...restProps
|
|
5705
5888
|
} = props;
|
|
5706
5889
|
const {
|
|
@@ -5727,20 +5910,39 @@ var MMDVisualNovelWithSelector = React10.forwardRef((props, ref) => {
|
|
|
5727
5910
|
return model?.path || stageModels[0]?.path || "";
|
|
5728
5911
|
}, [stageModels, selectedStageId]);
|
|
5729
5912
|
const modifiedScript = React10.useMemo(() => {
|
|
5913
|
+
if (resourceMappingMode === "full-clone") {
|
|
5914
|
+
return {
|
|
5915
|
+
...script,
|
|
5916
|
+
nodes: script.nodes.map((node) => ({
|
|
5917
|
+
...node,
|
|
5918
|
+
resources: {
|
|
5919
|
+
...node.resources,
|
|
5920
|
+
modelPath: selectedCharacterPath,
|
|
5921
|
+
stageModelPath: selectedStagePath
|
|
5922
|
+
}
|
|
5923
|
+
}))
|
|
5924
|
+
};
|
|
5925
|
+
}
|
|
5730
5926
|
return {
|
|
5731
5927
|
...script,
|
|
5732
|
-
nodes: script.nodes.map((node) =>
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5928
|
+
nodes: script.nodes.map((node) => {
|
|
5929
|
+
const nextModelPath = selectedCharacterPath;
|
|
5930
|
+
const nextStagePath = selectedStagePath;
|
|
5931
|
+
const resources = node.resources;
|
|
5932
|
+
if (resources.modelPath === nextModelPath && resources.stageModelPath === nextStagePath) {
|
|
5933
|
+
return node;
|
|
5934
|
+
}
|
|
5935
|
+
return {
|
|
5936
|
+
...node,
|
|
5937
|
+
resources: {
|
|
5938
|
+
...resources,
|
|
5939
|
+
modelPath: nextModelPath,
|
|
5940
|
+
stageModelPath: nextStagePath
|
|
5941
|
+
}
|
|
5942
|
+
};
|
|
5943
|
+
})
|
|
5742
5944
|
};
|
|
5743
|
-
}, [script, selectedCharacterPath, selectedStagePath]);
|
|
5945
|
+
}, [script, selectedCharacterPath, selectedStagePath, resourceMappingMode]);
|
|
5744
5946
|
const handleCharacterChange = React10.useCallback((id) => {
|
|
5745
5947
|
setSelectedCharacterId(id);
|
|
5746
5948
|
onModelSelectionChange?.(id, selectedStageId);
|
|
@@ -6323,594 +6525,733 @@ var MMDMusicPlayer = React10.forwardRef(
|
|
|
6323
6525
|
}
|
|
6324
6526
|
);
|
|
6325
6527
|
MMDMusicPlayer.displayName = "MMDMusicPlayer";
|
|
6326
|
-
|
|
6327
|
-
|
|
6528
|
+
|
|
6529
|
+
// src/mmd/ar/types.ts
|
|
6530
|
+
var ARMode = /* @__PURE__ */ ((ARMode2) => {
|
|
6531
|
+
ARMode2["Overlay"] = "overlay";
|
|
6532
|
+
ARMode2["WorldFixed"] = "world-fixed";
|
|
6533
|
+
return ARMode2;
|
|
6534
|
+
})(ARMode || {});
|
|
6535
|
+
|
|
6536
|
+
// src/mmd/ar/MMDARApp.tsx
|
|
6537
|
+
var DEFAULT_MODEL_SCALE = 0.1;
|
|
6538
|
+
function disposeMesh(object) {
|
|
6539
|
+
object.traverse((child) => {
|
|
6540
|
+
if (child instanceof THREE2__namespace.Mesh || child instanceof THREE2__namespace.SkinnedMesh) {
|
|
6541
|
+
if (child.geometry) {
|
|
6542
|
+
child.geometry.dispose();
|
|
6543
|
+
}
|
|
6544
|
+
const materials = Array.isArray(child.material) ? child.material : [child.material];
|
|
6545
|
+
materials.forEach((material) => {
|
|
6546
|
+
if (material instanceof THREE2__namespace.Material) {
|
|
6547
|
+
Object.values(material).forEach((value) => {
|
|
6548
|
+
if (value instanceof THREE2__namespace.Texture) {
|
|
6549
|
+
value.dispose();
|
|
6550
|
+
}
|
|
6551
|
+
});
|
|
6552
|
+
material.dispose();
|
|
6553
|
+
}
|
|
6554
|
+
});
|
|
6555
|
+
}
|
|
6556
|
+
});
|
|
6328
6557
|
}
|
|
6329
|
-
var
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6558
|
+
var MMDARApp = React10.forwardRef((props, ref) => {
|
|
6559
|
+
const {
|
|
6560
|
+
stage,
|
|
6561
|
+
mobileOptimization,
|
|
6562
|
+
cameraConfig,
|
|
6563
|
+
cameraParametersUrl,
|
|
6564
|
+
markerConfig,
|
|
6565
|
+
mirrored = false,
|
|
6566
|
+
showSettings,
|
|
6567
|
+
modelPresets,
|
|
6568
|
+
motionPresets,
|
|
6569
|
+
audioPresets,
|
|
6570
|
+
defaultModelId,
|
|
6571
|
+
defaultMotionId,
|
|
6572
|
+
defaultAudioId,
|
|
6573
|
+
modelScale,
|
|
6574
|
+
modelOffset,
|
|
6575
|
+
initialModelVisible = false,
|
|
6576
|
+
placementText = "Place Model",
|
|
6577
|
+
arMode,
|
|
6578
|
+
defaultARMode,
|
|
6579
|
+
autoPlay = true,
|
|
6580
|
+
loop = true,
|
|
6581
|
+
onCameraReady,
|
|
6582
|
+
onCameraError,
|
|
6583
|
+
onResourcesChange,
|
|
6584
|
+
onModelPlaced,
|
|
6585
|
+
onARModeChange,
|
|
6586
|
+
onLoad,
|
|
6587
|
+
onError,
|
|
6588
|
+
className,
|
|
6589
|
+
style
|
|
6590
|
+
} = props;
|
|
6335
6591
|
const containerRef = React10.useRef(null);
|
|
6592
|
+
const videoContainerRef = React10.useRef(null);
|
|
6336
6593
|
const canvasRef = React10.useRef(null);
|
|
6337
|
-
const sceneRef = React10.useRef();
|
|
6338
|
-
const cameraRef = React10.useRef();
|
|
6339
|
-
const rendererRef = React10.useRef();
|
|
6340
|
-
const arToolkitSourceRef = React10.useRef();
|
|
6341
|
-
const arToolkitContextRef = React10.useRef();
|
|
6342
|
-
const markerRootRef = React10.useRef();
|
|
6343
|
-
const markerControlsRef = React10.useRef();
|
|
6344
|
-
const modelRootRef = React10.useRef();
|
|
6345
|
-
const
|
|
6346
|
-
const
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
const
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
}
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6594
|
+
const sceneRef = React10.useRef(null);
|
|
6595
|
+
const cameraRef = React10.useRef(null);
|
|
6596
|
+
const rendererRef = React10.useRef(null);
|
|
6597
|
+
const arToolkitSourceRef = React10.useRef(null);
|
|
6598
|
+
const arToolkitContextRef = React10.useRef(null);
|
|
6599
|
+
const markerRootRef = React10.useRef(null);
|
|
6600
|
+
const markerControlsRef = React10.useRef(null);
|
|
6601
|
+
const modelRootRef = React10.useRef(null);
|
|
6602
|
+
const mmdHelperRef = React10.useRef(null);
|
|
6603
|
+
const mmdMeshRef = React10.useRef(null);
|
|
6604
|
+
const animationFrameRef = React10.useRef(null);
|
|
6605
|
+
const markerDetectedRef = React10.useRef(false);
|
|
6606
|
+
const audioRef = React10.useRef(null);
|
|
6607
|
+
const autoPlayRef = React10.useRef(autoPlay);
|
|
6608
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
6609
|
+
const [cameraReady, setCameraReady] = React10.useState(false);
|
|
6610
|
+
const [arReady, setArReady] = React10.useState(false);
|
|
6611
|
+
const [error, setError] = React10.useState(null);
|
|
6612
|
+
const [markerDetected, setMarkerDetected] = React10.useState(false);
|
|
6613
|
+
const [modelPlaced, setModelPlaced] = React10.useState(initialModelVisible);
|
|
6614
|
+
const [settingsVisible, setSettingsVisible] = React10.useState(showSettings ?? false);
|
|
6615
|
+
const [internalARMode, setInternalARMode] = React10.useState(
|
|
6616
|
+
defaultARMode ?? arMode ?? "overlay" /* Overlay */
|
|
6617
|
+
);
|
|
6618
|
+
const [cameraFacing, setCameraFacing] = React10.useState(
|
|
6619
|
+
cameraConfig?.facingMode ?? "environment"
|
|
6620
|
+
);
|
|
6621
|
+
const [selectedModelId, setSelectedModelId] = React10.useState(
|
|
6622
|
+
defaultModelId ?? modelPresets[0]?.id ?? ""
|
|
6623
|
+
);
|
|
6624
|
+
const [selectedMotionId, setSelectedMotionId] = React10.useState(
|
|
6625
|
+
defaultMotionId ?? motionPresets[0]?.id ?? ""
|
|
6626
|
+
);
|
|
6627
|
+
const [selectedAudioId, setSelectedAudioId] = React10.useState(
|
|
6628
|
+
defaultAudioId ?? audioPresets?.[0]?.id ?? ""
|
|
6629
|
+
);
|
|
6630
|
+
const [overrideResources, setOverrideResources] = React10.useState(null);
|
|
6631
|
+
const resolvedARMode = arMode ?? internalARMode;
|
|
6632
|
+
const resolvedMarkerConfig = React10.useMemo(() => {
|
|
6633
|
+
return {
|
|
6634
|
+
type: markerConfig?.type ?? "pattern",
|
|
6635
|
+
patternUrl: markerConfig?.patternUrl ?? chunkFGQGWW73_js.DEFAULT_AR_ASSETS.patternUrl,
|
|
6636
|
+
barcodeValue: markerConfig?.barcodeValue ?? 0,
|
|
6637
|
+
changeMatrixMode: markerConfig?.changeMatrixMode ?? "modelViewMatrix"
|
|
6638
|
+
};
|
|
6639
|
+
}, [markerConfig]);
|
|
6640
|
+
const resolvedResources = React10.useMemo(() => {
|
|
6641
|
+
if (overrideResources) {
|
|
6642
|
+
return overrideResources;
|
|
6385
6643
|
}
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6644
|
+
const modelPreset = modelPresets.find((preset) => preset.id === selectedModelId);
|
|
6645
|
+
if (!modelPreset) {
|
|
6646
|
+
return null;
|
|
6647
|
+
}
|
|
6648
|
+
const motionPreset = motionPresets.find((preset) => preset.id === selectedMotionId);
|
|
6649
|
+
const audioPreset = audioPresets?.find((preset) => preset.id === selectedAudioId);
|
|
6650
|
+
return {
|
|
6651
|
+
modelPath: modelPreset.modelPath,
|
|
6652
|
+
motionPath: motionPreset?.motionPath,
|
|
6653
|
+
audioPath: audioPreset?.audioPath
|
|
6654
|
+
};
|
|
6655
|
+
}, [
|
|
6656
|
+
overrideResources,
|
|
6657
|
+
modelPresets,
|
|
6658
|
+
motionPresets,
|
|
6659
|
+
audioPresets,
|
|
6660
|
+
selectedModelId,
|
|
6661
|
+
selectedMotionId,
|
|
6662
|
+
selectedAudioId
|
|
6663
|
+
]);
|
|
6664
|
+
const resolveModelScale = React10.useCallback(() => {
|
|
6665
|
+
if (!modelScale) {
|
|
6666
|
+
return new THREE2__namespace.Vector3(DEFAULT_MODEL_SCALE, DEFAULT_MODEL_SCALE, DEFAULT_MODEL_SCALE);
|
|
6667
|
+
}
|
|
6668
|
+
if (typeof modelScale === "number") {
|
|
6669
|
+
return new THREE2__namespace.Vector3(modelScale, modelScale, modelScale);
|
|
6670
|
+
}
|
|
6671
|
+
return new THREE2__namespace.Vector3(modelScale.x, modelScale.y, modelScale.z);
|
|
6672
|
+
}, [modelScale]);
|
|
6673
|
+
const applyModelTransform = React10.useCallback(
|
|
6674
|
+
(mesh) => {
|
|
6675
|
+
const scale = resolveModelScale();
|
|
6676
|
+
mesh.scale.copy(scale);
|
|
6677
|
+
if (modelOffset) {
|
|
6678
|
+
mesh.position.set(modelOffset.x, modelOffset.y, modelOffset.z);
|
|
6679
|
+
return;
|
|
6392
6680
|
}
|
|
6393
|
-
|
|
6394
|
-
if (
|
|
6395
|
-
|
|
6396
|
-
console.log("Querying camera permission status...");
|
|
6397
|
-
const permissionPromise = navigator.permissions.query({ name: "camera" });
|
|
6398
|
-
const timeoutPromise2 = new Promise((_, reject) => {
|
|
6399
|
-
setTimeout(() => reject(new Error("Permission query timeout")), 5e3);
|
|
6400
|
-
});
|
|
6401
|
-
const permissionStatus = await Promise.race([permissionPromise, timeoutPromise2]);
|
|
6402
|
-
console.log("Permission status:", permissionStatus.state);
|
|
6403
|
-
if (permissionStatus.state === "denied") {
|
|
6404
|
-
throw new Error("\u6444\u50CF\u5934\u6743\u9650\u5DF2\u88AB\u62D2\u7EDD\uFF0C\u8BF7\u5728\u6D4F\u89C8\u5668\u8BBE\u7F6E\u4E2D\u5141\u8BB8\u8BBF\u95EE\u6444\u50CF\u5934");
|
|
6405
|
-
}
|
|
6406
|
-
} catch (permissionError) {
|
|
6407
|
-
console.warn("Permission query failed or timed out, proceeding with getUserMedia:", permissionError);
|
|
6408
|
-
}
|
|
6681
|
+
const box = new THREE2__namespace.Box3().setFromObject(mesh);
|
|
6682
|
+
if (Number.isFinite(box.min.y)) {
|
|
6683
|
+
mesh.position.y += -box.min.y;
|
|
6409
6684
|
}
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6685
|
+
},
|
|
6686
|
+
[modelOffset, resolveModelScale]
|
|
6687
|
+
);
|
|
6688
|
+
const updateModelPlacement = React10.useCallback(
|
|
6689
|
+
(visible) => {
|
|
6690
|
+
if (!modelRootRef.current) return;
|
|
6691
|
+
modelRootRef.current.visible = visible;
|
|
6692
|
+
setModelPlaced(visible);
|
|
6693
|
+
},
|
|
6694
|
+
[]
|
|
6695
|
+
);
|
|
6696
|
+
const attachModelRoot = React10.useCallback(
|
|
6697
|
+
(mode) => {
|
|
6698
|
+
if (!modelRootRef.current || !sceneRef.current || !cameraRef.current) return;
|
|
6699
|
+
if (mode === "overlay" /* Overlay */) {
|
|
6700
|
+
if (modelRootRef.current.parent !== cameraRef.current) {
|
|
6701
|
+
modelRootRef.current.parent?.remove(modelRootRef.current);
|
|
6702
|
+
cameraRef.current.add(modelRootRef.current);
|
|
6703
|
+
}
|
|
6704
|
+
modelRootRef.current.position.set(0, -1, -3);
|
|
6705
|
+
modelRootRef.current.quaternion.identity();
|
|
6706
|
+
updateModelPlacement(true);
|
|
6707
|
+
} else {
|
|
6708
|
+
if (modelRootRef.current.parent !== sceneRef.current) {
|
|
6709
|
+
modelRootRef.current.parent?.remove(modelRootRef.current);
|
|
6710
|
+
sceneRef.current.add(modelRootRef.current);
|
|
6417
6711
|
}
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
const errorMessage = error instanceof Error ? error.message : "\u65E0\u6CD5\u8BBF\u95EE\u6444\u50CF\u5934";
|
|
6430
|
-
setState((prev) => ({ ...prev, error: errorMessage, isLoading: false }));
|
|
6431
|
-
onError?.(errorMessage);
|
|
6432
|
-
return false;
|
|
6433
|
-
}
|
|
6434
|
-
}, [width, height, onError]);
|
|
6435
|
-
const createModel = React10.useCallback((modelType) => {
|
|
6436
|
-
let geometry;
|
|
6437
|
-
let material;
|
|
6438
|
-
let mesh;
|
|
6439
|
-
switch (modelType) {
|
|
6440
|
-
case "sphere":
|
|
6441
|
-
geometry = new THREE2__namespace.SphereGeometry(0.5, 32, 32);
|
|
6442
|
-
material = new THREE2__namespace.MeshPhongMaterial({
|
|
6443
|
-
color: 16738740,
|
|
6444
|
-
shininess: 100,
|
|
6445
|
-
specular: 1118481
|
|
6446
|
-
});
|
|
6447
|
-
mesh = new THREE2__namespace.Mesh(geometry, material);
|
|
6448
|
-
break;
|
|
6449
|
-
case "cube":
|
|
6450
|
-
geometry = new THREE2__namespace.BoxGeometry(0.8, 0.8, 0.8);
|
|
6451
|
-
material = new THREE2__namespace.MeshPhongMaterial({
|
|
6452
|
-
color: 65407,
|
|
6453
|
-
shininess: 100,
|
|
6454
|
-
specular: 1118481
|
|
6455
|
-
});
|
|
6456
|
-
mesh = new THREE2__namespace.Mesh(geometry, material);
|
|
6457
|
-
break;
|
|
6458
|
-
case "torus":
|
|
6459
|
-
geometry = new THREE2__namespace.TorusGeometry(0.4, 0.2, 16, 100);
|
|
6460
|
-
material = new THREE2__namespace.MeshPhongMaterial({
|
|
6461
|
-
color: 16753920,
|
|
6462
|
-
shininess: 100,
|
|
6463
|
-
specular: 1118481
|
|
6464
|
-
});
|
|
6465
|
-
mesh = new THREE2__namespace.Mesh(geometry, material);
|
|
6466
|
-
break;
|
|
6467
|
-
default:
|
|
6468
|
-
geometry = new THREE2__namespace.SphereGeometry(0.5, 32, 32);
|
|
6469
|
-
material = new THREE2__namespace.MeshPhongMaterial({
|
|
6470
|
-
color: 16738740,
|
|
6471
|
-
shininess: 100,
|
|
6472
|
-
specular: 1118481
|
|
6473
|
-
});
|
|
6474
|
-
mesh = new THREE2__namespace.Mesh(geometry, material);
|
|
6712
|
+
updateModelPlacement(initialModelVisible);
|
|
6713
|
+
}
|
|
6714
|
+
},
|
|
6715
|
+
[initialModelVisible, updateModelPlacement]
|
|
6716
|
+
);
|
|
6717
|
+
const stopCameraStream = React10.useCallback(() => {
|
|
6718
|
+
const source = arToolkitSourceRef.current;
|
|
6719
|
+
if (!source?.domElement) return;
|
|
6720
|
+
const stream = source.domElement.srcObject;
|
|
6721
|
+
if (stream) {
|
|
6722
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
6475
6723
|
}
|
|
6476
|
-
mesh.rotation.x = Math.PI / 4;
|
|
6477
|
-
mesh.rotation.y = Math.PI / 4;
|
|
6478
|
-
return mesh;
|
|
6479
6724
|
}, []);
|
|
6480
|
-
const
|
|
6481
|
-
|
|
6482
|
-
|
|
6725
|
+
const cleanupAR = React10.useCallback(() => {
|
|
6726
|
+
stopCameraStream();
|
|
6727
|
+
if (markerRootRef.current && sceneRef.current) {
|
|
6728
|
+
sceneRef.current.remove(markerRootRef.current);
|
|
6729
|
+
markerRootRef.current.clear();
|
|
6730
|
+
}
|
|
6731
|
+
markerRootRef.current = null;
|
|
6732
|
+
markerControlsRef.current = null;
|
|
6733
|
+
const videoContainer = videoContainerRef.current;
|
|
6734
|
+
const videoElement = arToolkitSourceRef.current?.domElement;
|
|
6735
|
+
if (videoContainer && videoElement && videoElement.parentElement === videoContainer) {
|
|
6736
|
+
videoContainer.removeChild(videoElement);
|
|
6737
|
+
}
|
|
6738
|
+
arToolkitSourceRef.current?.dispose?.();
|
|
6739
|
+
arToolkitSourceRef.current = null;
|
|
6740
|
+
arToolkitContextRef.current = null;
|
|
6741
|
+
markerDetectedRef.current = false;
|
|
6742
|
+
setMarkerDetected(false);
|
|
6743
|
+
setCameraReady(false);
|
|
6744
|
+
setArReady(false);
|
|
6745
|
+
}, [stopCameraStream]);
|
|
6746
|
+
const setupRenderer = React10.useCallback(() => {
|
|
6747
|
+
if (rendererRef.current) return;
|
|
6748
|
+
if (!canvasRef.current) return;
|
|
6749
|
+
const renderer = new THREE2__namespace.WebGLRenderer({
|
|
6750
|
+
canvas: canvasRef.current,
|
|
6751
|
+
antialias: true,
|
|
6752
|
+
alpha: true
|
|
6753
|
+
});
|
|
6754
|
+
renderer.setClearColor(0, 0);
|
|
6755
|
+
renderer.setPixelRatio(mobileOptimization?.pixelRatio ?? window.devicePixelRatio ?? 1);
|
|
6756
|
+
rendererRef.current = renderer;
|
|
6757
|
+
const scene = new THREE2__namespace.Scene();
|
|
6758
|
+
sceneRef.current = scene;
|
|
6759
|
+
const camera = new THREE2__namespace.Camera();
|
|
6760
|
+
cameraRef.current = camera;
|
|
6761
|
+
scene.add(camera);
|
|
6762
|
+
const modelRoot = new THREE2__namespace.Group();
|
|
6763
|
+
modelRoot.visible = initialModelVisible;
|
|
6764
|
+
modelRootRef.current = modelRoot;
|
|
6765
|
+
scene.add(modelRoot);
|
|
6766
|
+
const ambientLight = new THREE2__namespace.AmbientLight(
|
|
6767
|
+
16777215,
|
|
6768
|
+
stage?.ambientLightIntensity ?? 0.8
|
|
6769
|
+
);
|
|
6770
|
+
scene.add(ambientLight);
|
|
6771
|
+
const directionalLight = new THREE2__namespace.DirectionalLight(
|
|
6772
|
+
16777215,
|
|
6773
|
+
stage?.directionalLightIntensity ?? 0.6
|
|
6774
|
+
);
|
|
6775
|
+
directionalLight.position.set(1, 1, 1);
|
|
6776
|
+
scene.add(directionalLight);
|
|
6777
|
+
attachModelRoot(resolvedARMode);
|
|
6778
|
+
}, [
|
|
6779
|
+
attachModelRoot,
|
|
6780
|
+
initialModelVisible,
|
|
6781
|
+
mobileOptimization?.pixelRatio,
|
|
6782
|
+
resolvedARMode,
|
|
6783
|
+
stage?.ambientLightIntensity,
|
|
6784
|
+
stage?.directionalLightIntensity
|
|
6785
|
+
]);
|
|
6786
|
+
const resize = React10.useCallback(() => {
|
|
6787
|
+
if (!containerRef.current || !rendererRef.current) return;
|
|
6788
|
+
const width = containerRef.current.clientWidth;
|
|
6789
|
+
const height = containerRef.current.clientHeight;
|
|
6790
|
+
if (width === 0 || height === 0) return;
|
|
6791
|
+
rendererRef.current.setSize(width, height);
|
|
6792
|
+
const source = arToolkitSourceRef.current;
|
|
6793
|
+
if (source?.onResizeElement && source?.copyElementSizeTo) {
|
|
6794
|
+
source.onResizeElement();
|
|
6795
|
+
source.copyElementSizeTo(rendererRef.current.domElement);
|
|
6796
|
+
if (arToolkitContextRef.current?.arController?.canvas) {
|
|
6797
|
+
source.copyElementSizeTo(arToolkitContextRef.current.arController.canvas);
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
}, []);
|
|
6801
|
+
const startRenderLoop = React10.useCallback(() => {
|
|
6802
|
+
if (animationFrameRef.current) return;
|
|
6803
|
+
if (!rendererRef.current || !sceneRef.current || !cameraRef.current) return;
|
|
6804
|
+
const renderer = rendererRef.current;
|
|
6805
|
+
const scene = sceneRef.current;
|
|
6806
|
+
const camera = cameraRef.current;
|
|
6807
|
+
const clock = new THREE2__namespace.Clock();
|
|
6808
|
+
const render = () => {
|
|
6809
|
+
animationFrameRef.current = requestAnimationFrame(render);
|
|
6810
|
+
if (arToolkitSourceRef.current?.ready) {
|
|
6811
|
+
arToolkitContextRef.current?.update(arToolkitSourceRef.current.domElement);
|
|
6812
|
+
if (markerRootRef.current) {
|
|
6813
|
+
const isVisible = markerRootRef.current.visible;
|
|
6814
|
+
if (isVisible !== markerDetectedRef.current) {
|
|
6815
|
+
markerDetectedRef.current = isVisible;
|
|
6816
|
+
setMarkerDetected(isVisible);
|
|
6817
|
+
}
|
|
6818
|
+
}
|
|
6819
|
+
}
|
|
6820
|
+
if (mmdHelperRef.current && autoPlayRef.current) {
|
|
6821
|
+
const delta = clock.getDelta();
|
|
6822
|
+
mmdHelperRef.current.update(delta);
|
|
6823
|
+
}
|
|
6824
|
+
renderer.render(scene, camera);
|
|
6825
|
+
};
|
|
6826
|
+
render();
|
|
6827
|
+
}, []);
|
|
6828
|
+
const setupAR = React10.useCallback(async (facingOverride) => {
|
|
6829
|
+
if (!sceneRef.current || !cameraRef.current) return;
|
|
6830
|
+
const THREEx = await chunkFGQGWW73_js.loadARJS({ three: THREE2__namespace });
|
|
6831
|
+
const facingMode = facingOverride ?? cameraFacing;
|
|
6832
|
+
const sourceWidth = typeof cameraConfig?.width === "number" ? cameraConfig.width : cameraConfig?.width?.ideal;
|
|
6833
|
+
const sourceHeight = typeof cameraConfig?.height === "number" ? cameraConfig.height : cameraConfig?.height?.ideal;
|
|
6834
|
+
const arToolkitSource = new THREEx.ArToolkitSource({
|
|
6835
|
+
sourceType: "webcam",
|
|
6836
|
+
sourceWidth: sourceWidth ?? 1280,
|
|
6837
|
+
sourceHeight: sourceHeight ?? 720,
|
|
6838
|
+
facingMode
|
|
6839
|
+
});
|
|
6840
|
+
arToolkitSourceRef.current = arToolkitSource;
|
|
6841
|
+
const arToolkitContext = new THREEx.ArToolkitContext({
|
|
6842
|
+
cameraParametersUrl: cameraParametersUrl ?? chunkFGQGWW73_js.DEFAULT_AR_ASSETS.cameraParametersUrl,
|
|
6843
|
+
detectionMode: "mono",
|
|
6844
|
+
maxDetectionRate: 30
|
|
6845
|
+
});
|
|
6846
|
+
arToolkitContextRef.current = arToolkitContext;
|
|
6847
|
+
const markerRoot = new THREE2__namespace.Group();
|
|
6848
|
+
markerRootRef.current = markerRoot;
|
|
6849
|
+
sceneRef.current.add(markerRoot);
|
|
6850
|
+
markerControlsRef.current = new THREEx.ArMarkerControls(
|
|
6851
|
+
arToolkitContext,
|
|
6852
|
+
markerRoot,
|
|
6853
|
+
resolvedMarkerConfig
|
|
6854
|
+
);
|
|
6855
|
+
arToolkitContext.init(() => {
|
|
6856
|
+
if (!cameraRef.current) return;
|
|
6857
|
+
cameraRef.current.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
|
|
6858
|
+
setArReady(true);
|
|
6859
|
+
});
|
|
6860
|
+
arToolkitSource.init(() => {
|
|
6861
|
+
const videoElement = arToolkitSource.domElement;
|
|
6862
|
+
if (videoContainerRef.current && videoElement.parentElement !== videoContainerRef.current) {
|
|
6863
|
+
videoContainerRef.current.appendChild(videoElement);
|
|
6864
|
+
}
|
|
6865
|
+
videoElement.setAttribute("playsinline", "true");
|
|
6866
|
+
videoElement.style.position = "absolute";
|
|
6867
|
+
videoElement.style.inset = "0";
|
|
6868
|
+
videoElement.style.width = "100%";
|
|
6869
|
+
videoElement.style.height = "100%";
|
|
6870
|
+
videoElement.style.objectFit = "cover";
|
|
6871
|
+
videoElement.style.zIndex = "0";
|
|
6872
|
+
if (mirrored) {
|
|
6873
|
+
videoElement.style.transform = "scaleX(-1)";
|
|
6874
|
+
}
|
|
6875
|
+
setCameraReady(true);
|
|
6876
|
+
const stream = videoElement.srcObject;
|
|
6877
|
+
if (stream) {
|
|
6878
|
+
onCameraReady?.(stream);
|
|
6879
|
+
}
|
|
6880
|
+
resize();
|
|
6881
|
+
});
|
|
6882
|
+
}, [
|
|
6883
|
+
cameraConfig?.height,
|
|
6884
|
+
cameraConfig?.width,
|
|
6885
|
+
cameraFacing,
|
|
6886
|
+
cameraParametersUrl,
|
|
6887
|
+
mirrored,
|
|
6888
|
+
onCameraReady,
|
|
6889
|
+
resize,
|
|
6890
|
+
resolvedMarkerConfig
|
|
6891
|
+
]);
|
|
6892
|
+
const loadMMDResources = React10.useCallback(async () => {
|
|
6893
|
+
if (!resolvedResources || !sceneRef.current || !modelRootRef.current) {
|
|
6483
6894
|
return;
|
|
6484
6895
|
}
|
|
6896
|
+
setIsLoading(true);
|
|
6897
|
+
setError(null);
|
|
6898
|
+
if (mmdMeshRef.current) {
|
|
6899
|
+
if (mmdHelperRef.current) {
|
|
6900
|
+
mmdHelperRef.current.remove(mmdMeshRef.current);
|
|
6901
|
+
}
|
|
6902
|
+
modelRootRef.current.remove(mmdMeshRef.current);
|
|
6903
|
+
disposeMesh(mmdMeshRef.current);
|
|
6904
|
+
mmdMeshRef.current = null;
|
|
6905
|
+
}
|
|
6906
|
+
if (!mmdHelperRef.current) {
|
|
6907
|
+
mmdHelperRef.current = new threeStdlib.MMDAnimationHelper({ afterglow: 2 });
|
|
6908
|
+
}
|
|
6909
|
+
const loader = new threeStdlib.MMDLoader();
|
|
6910
|
+
const loadModel = () => new Promise((resolve, reject) => {
|
|
6911
|
+
if (resolvedResources.motionPath) {
|
|
6912
|
+
loader.loadWithAnimation(
|
|
6913
|
+
resolvedResources.modelPath,
|
|
6914
|
+
resolvedResources.motionPath,
|
|
6915
|
+
(mmd) => resolve({ mesh: mmd.mesh, animation: mmd.animation }),
|
|
6916
|
+
void 0,
|
|
6917
|
+
(err) => reject(err)
|
|
6918
|
+
);
|
|
6919
|
+
} else {
|
|
6920
|
+
loader.load(
|
|
6921
|
+
resolvedResources.modelPath,
|
|
6922
|
+
(mesh) => resolve({ mesh }),
|
|
6923
|
+
void 0,
|
|
6924
|
+
(err) => reject(err)
|
|
6925
|
+
);
|
|
6926
|
+
}
|
|
6927
|
+
});
|
|
6485
6928
|
try {
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6929
|
+
const { mesh, animation } = await loadModel();
|
|
6930
|
+
configureMaterialsForMMD(mesh, {
|
|
6931
|
+
enableGradientMap: true,
|
|
6932
|
+
shininess: 30,
|
|
6933
|
+
specularColor: 8947848
|
|
6934
|
+
});
|
|
6935
|
+
applyModelTransform(mesh);
|
|
6936
|
+
mesh.castShadow = true;
|
|
6937
|
+
mesh.receiveShadow = stage?.modelReceiveShadow ?? true;
|
|
6938
|
+
mmdMeshRef.current = mesh;
|
|
6939
|
+
modelRootRef.current.add(mesh);
|
|
6940
|
+
if (animation) {
|
|
6941
|
+
mmdHelperRef.current.add(mesh, {
|
|
6942
|
+
animation,
|
|
6943
|
+
physics: false
|
|
6944
|
+
});
|
|
6945
|
+
}
|
|
6946
|
+
setIsLoading(false);
|
|
6947
|
+
onResourcesChange?.(resolvedResources);
|
|
6948
|
+
onLoad?.();
|
|
6949
|
+
} catch (err) {
|
|
6950
|
+
const message = err instanceof Error ? err.message : "Failed to load MMD resources";
|
|
6951
|
+
setError(message);
|
|
6952
|
+
setIsLoading(false);
|
|
6953
|
+
onError?.(err instanceof Error ? err : new Error(message));
|
|
6954
|
+
}
|
|
6955
|
+
}, [applyModelTransform, onError, onLoad, onResourcesChange, resolvedResources, stage?.modelReceiveShadow]);
|
|
6956
|
+
const updateAudio = React10.useCallback(() => {
|
|
6957
|
+
if (!resolvedResources?.audioPath) {
|
|
6958
|
+
if (audioRef.current) {
|
|
6959
|
+
audioRef.current.pause();
|
|
6960
|
+
audioRef.current.src = "";
|
|
6961
|
+
audioRef.current = null;
|
|
6962
|
+
}
|
|
6963
|
+
return;
|
|
6500
6964
|
}
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
if (setting === "cameraFacing" || setting === "markerType" || setting === "quality") {
|
|
6505
|
-
setTimeout(() => {
|
|
6506
|
-
alert("\u6B64\u8BBE\u7F6E\u53D8\u66F4\u9700\u8981\u91CD\u65B0\u542F\u52A8 AR \u7CFB\u7EDF\u3002\u8BF7\u5237\u65B0\u9875\u9762\u4EE5\u5E94\u7528\u65B0\u8BBE\u7F6E\u3002");
|
|
6507
|
-
}, 100);
|
|
6965
|
+
if (audioRef.current) {
|
|
6966
|
+
audioRef.current.pause();
|
|
6967
|
+
audioRef.current.src = "";
|
|
6508
6968
|
}
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6969
|
+
const audio = new Audio(resolvedResources.audioPath);
|
|
6970
|
+
audio.loop = loop;
|
|
6971
|
+
audioRef.current = audio;
|
|
6972
|
+
if (autoPlay || modelPlaced) {
|
|
6973
|
+
audio.play().catch(() => void 0);
|
|
6974
|
+
}
|
|
6975
|
+
}, [autoPlay, loop, modelPlaced, resolvedResources?.audioPath]);
|
|
6976
|
+
const placeModel = React10.useCallback(() => {
|
|
6977
|
+
if (!modelRootRef.current) return;
|
|
6978
|
+
if (resolvedARMode === "overlay" /* Overlay */) {
|
|
6979
|
+
updateModelPlacement(true);
|
|
6980
|
+
onModelPlaced?.();
|
|
6513
6981
|
return;
|
|
6514
6982
|
}
|
|
6515
|
-
|
|
6983
|
+
if (!markerRootRef.current) return;
|
|
6984
|
+
modelRootRef.current.position.copy(markerRootRef.current.position);
|
|
6985
|
+
modelRootRef.current.quaternion.copy(markerRootRef.current.quaternion);
|
|
6986
|
+
updateModelPlacement(true);
|
|
6987
|
+
onModelPlaced?.();
|
|
6988
|
+
}, [onModelPlaced, resolvedARMode, updateModelPlacement]);
|
|
6989
|
+
const removeModel = React10.useCallback(() => {
|
|
6990
|
+
updateModelPlacement(false);
|
|
6991
|
+
}, [updateModelPlacement]);
|
|
6992
|
+
React10.useImperativeHandle(ref, () => ({
|
|
6993
|
+
startCamera: async () => {
|
|
6994
|
+
cleanupAR();
|
|
6995
|
+
await setupAR();
|
|
6996
|
+
},
|
|
6997
|
+
stopCamera: () => {
|
|
6998
|
+
cleanupAR();
|
|
6999
|
+
},
|
|
7000
|
+
switchCamera: async () => {
|
|
7001
|
+
const next = cameraFacing === "environment" ? "user" : "environment";
|
|
7002
|
+
setCameraFacing(next);
|
|
7003
|
+
cleanupAR();
|
|
7004
|
+
await setupAR(next);
|
|
7005
|
+
},
|
|
7006
|
+
snapshot: async () => {
|
|
7007
|
+
if (!rendererRef.current) return "";
|
|
6516
7008
|
const canvas = document.createElement("canvas");
|
|
6517
7009
|
const context = canvas.getContext("2d");
|
|
6518
|
-
if (!context)
|
|
6519
|
-
|
|
6520
|
-
|
|
7010
|
+
if (!context) return "";
|
|
7011
|
+
const width = rendererRef.current.domElement.width;
|
|
7012
|
+
const height = rendererRef.current.domElement.height;
|
|
6521
7013
|
canvas.width = width;
|
|
6522
7014
|
canvas.height = height;
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
context.drawImage(rendererCanvas, 0, 0, width, height);
|
|
6526
|
-
if (arToolkitSourceRef.current && arToolkitSourceRef.current.domElement) {
|
|
6527
|
-
const videoElement = arToolkitSourceRef.current.domElement;
|
|
6528
|
-
context.globalCompositeOperation = "source-over";
|
|
7015
|
+
const videoElement = arToolkitSourceRef.current?.domElement;
|
|
7016
|
+
if (videoElement) {
|
|
6529
7017
|
context.drawImage(videoElement, 0, 0, width, height);
|
|
6530
7018
|
}
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
}
|
|
6543
|
-
}, "image/png");
|
|
6544
|
-
} catch (error) {
|
|
6545
|
-
console.error("Failed to take photo:", error);
|
|
6546
|
-
setState((prev) => ({ ...prev, error: "\u62CD\u7167\u5931\u8D25" }));
|
|
6547
|
-
}
|
|
6548
|
-
}, [width, height]);
|
|
6549
|
-
const initializeAR = React10.useCallback(async () => {
|
|
6550
|
-
try {
|
|
6551
|
-
console.log("Starting AR initialization...");
|
|
6552
|
-
if (!window.__arjs_ready) {
|
|
6553
|
-
console.log("Waiting for AR.js initialization...");
|
|
6554
|
-
await new Promise((resolve, reject) => {
|
|
6555
|
-
const check = setInterval(() => {
|
|
6556
|
-
if (window.__arjs_ready) {
|
|
6557
|
-
clearInterval(check);
|
|
6558
|
-
console.log("AR.js initialization complete!");
|
|
6559
|
-
resolve();
|
|
6560
|
-
}
|
|
6561
|
-
}, 50);
|
|
6562
|
-
setTimeout(() => {
|
|
6563
|
-
clearInterval(check);
|
|
6564
|
-
reject(new Error("AR.js initialization timeout"));
|
|
6565
|
-
}, 15e3);
|
|
6566
|
-
});
|
|
7019
|
+
context.drawImage(rendererRef.current.domElement, 0, 0, width, height);
|
|
7020
|
+
return canvas.toDataURL("image/png");
|
|
7021
|
+
},
|
|
7022
|
+
placeModel,
|
|
7023
|
+
removeModel,
|
|
7024
|
+
switchModel: (resources) => {
|
|
7025
|
+
setOverrideResources(resources);
|
|
7026
|
+
},
|
|
7027
|
+
setARMode: (mode) => {
|
|
7028
|
+
if (!arMode) {
|
|
7029
|
+
setInternalARMode(mode);
|
|
6567
7030
|
}
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
...state.cameraFacing && { facingMode: state.cameraFacing }
|
|
6588
|
-
});
|
|
6589
|
-
arToolkitSourceRef.current = arToolkitSource;
|
|
6590
|
-
const arToolkitContext = new THREEx.ArToolkitContext({
|
|
6591
|
-
cameraParametersUrl: "data/camera_para.dat",
|
|
6592
|
-
// 使用内建相机参数
|
|
6593
|
-
detectionMode: "mono",
|
|
6594
|
-
// 根据质量设置调整检测参数
|
|
6595
|
-
...state.quality && {
|
|
6596
|
-
maxDetectionRate: state.quality === "high" ? 60 : state.quality === "medium" ? 30 : 15
|
|
6597
|
-
}
|
|
6598
|
-
});
|
|
6599
|
-
arToolkitContextRef.current = arToolkitContext;
|
|
6600
|
-
arToolkitContext.init(() => {
|
|
6601
|
-
cameraRef.current.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
|
|
6602
|
-
const markerRoot = new THREE2__namespace.Group();
|
|
6603
|
-
sceneRef.current.add(markerRoot);
|
|
6604
|
-
markerRootRef.current = markerRoot;
|
|
6605
|
-
const markerGeometry = new THREE2__namespace.BoxGeometry(1, 1, 0.1);
|
|
6606
|
-
const markerMaterial = new THREE2__namespace.MeshBasicMaterial({
|
|
6607
|
-
color: 65280,
|
|
6608
|
-
transparent: true,
|
|
6609
|
-
opacity: 0.7,
|
|
6610
|
-
wireframe: state.showWireframe
|
|
6611
|
-
// 根据设置显示线框
|
|
6612
|
-
});
|
|
6613
|
-
const markerMesh = new THREE2__namespace.Mesh(markerGeometry, markerMaterial);
|
|
6614
|
-
markerMesh.position.set(0, 0, 0);
|
|
6615
|
-
markerRoot.add(markerMesh);
|
|
6616
|
-
if (!state.showWireframe) {
|
|
6617
|
-
const edges = new THREE2__namespace.EdgesGeometry(markerGeometry);
|
|
6618
|
-
const lineMaterial = new THREE2__namespace.LineBasicMaterial({ color: 16777215 });
|
|
6619
|
-
const wireframe = new THREE2__namespace.LineSegments(edges, lineMaterial);
|
|
6620
|
-
markerRoot.add(wireframe);
|
|
6621
|
-
}
|
|
6622
|
-
const markerControls = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, {
|
|
6623
|
-
type: state.markerType,
|
|
6624
|
-
...state.markerType === "barcode" ? { barcodeValue: 0 } : { patternUrl: "data/patt.hiro" }
|
|
6625
|
-
});
|
|
6626
|
-
markerControlsRef.current = markerControls;
|
|
6627
|
-
if (state.lightingEnabled) {
|
|
6628
|
-
const ambientLight = new THREE2__namespace.AmbientLight(4210752, 0.6);
|
|
6629
|
-
sceneRef.current.add(ambientLight);
|
|
6630
|
-
const directionalLight = new THREE2__namespace.DirectionalLight(16777215, 0.8);
|
|
6631
|
-
directionalLight.position.set(1, 1, 1);
|
|
6632
|
-
sceneRef.current.add(directionalLight);
|
|
6633
|
-
}
|
|
6634
|
-
const modelRoot = new THREE2__namespace.Group();
|
|
6635
|
-
modelRoot.visible = false;
|
|
6636
|
-
sceneRef.current.add(modelRoot);
|
|
6637
|
-
modelRootRef.current = modelRoot;
|
|
6638
|
-
setState((prev) => ({
|
|
6639
|
-
...prev,
|
|
6640
|
-
arReady: true,
|
|
6641
|
-
isLoading: false
|
|
6642
|
-
}));
|
|
6643
|
-
onReady?.();
|
|
6644
|
-
console.log("AR.js and marker system initialized successfully");
|
|
6645
|
-
});
|
|
6646
|
-
arToolkitSource.init(() => {
|
|
6647
|
-
arToolkitSource.domElement.style.display = "none";
|
|
6648
|
-
setState((prev) => ({ ...prev, cameraReady: true }));
|
|
6649
|
-
console.log("Camera initialized successfully");
|
|
6650
|
-
});
|
|
6651
|
-
return true;
|
|
6652
|
-
} catch (error) {
|
|
6653
|
-
console.error("Failed to initialize AR.js:", error);
|
|
6654
|
-
const errorMessage = error instanceof Error ? error.message : "AR.js \u521D\u59CB\u5316\u5931\u8D25";
|
|
6655
|
-
setState((prev) => ({
|
|
6656
|
-
...prev,
|
|
6657
|
-
error: errorMessage,
|
|
6658
|
-
isLoading: false
|
|
6659
|
-
}));
|
|
6660
|
-
onError?.(errorMessage);
|
|
6661
|
-
return false;
|
|
6662
|
-
}
|
|
6663
|
-
}, [width, height, requestCameraPermission, onReady, onError]);
|
|
6664
|
-
const render = React10.useCallback(() => {
|
|
6665
|
-
if (!rendererRef.current || !sceneRef.current || !cameraRef.current) return;
|
|
6666
|
-
requestAnimationFrame(render);
|
|
6667
|
-
if (arToolkitSourceRef.current && arToolkitSourceRef.current.ready) {
|
|
6668
|
-
arToolkitContextRef.current.update(arToolkitSourceRef.current.domElement);
|
|
6669
|
-
if (markerRootRef.current && markerRootRef.current.visible !== state.markerDetected) {
|
|
6670
|
-
setState((prev) => ({ ...prev, markerDetected: markerRootRef.current.visible }));
|
|
7031
|
+
attachModelRoot(mode);
|
|
7032
|
+
onARModeChange?.(mode);
|
|
7033
|
+
},
|
|
7034
|
+
getARMode: () => resolvedARMode
|
|
7035
|
+
}));
|
|
7036
|
+
React10.useEffect(() => {
|
|
7037
|
+
autoPlayRef.current = autoPlay || modelPlaced;
|
|
7038
|
+
}, [autoPlay, modelPlaced]);
|
|
7039
|
+
React10.useEffect(() => {
|
|
7040
|
+
if (showSettings !== void 0) {
|
|
7041
|
+
setSettingsVisible(showSettings);
|
|
7042
|
+
}
|
|
7043
|
+
}, [showSettings]);
|
|
7044
|
+
React10.useEffect(() => {
|
|
7045
|
+
if (cameraConfig?.facingMode) {
|
|
7046
|
+
if (cameraConfig.facingMode !== cameraFacing) {
|
|
7047
|
+
setCameraFacing(cameraConfig.facingMode);
|
|
7048
|
+
cleanupAR();
|
|
7049
|
+
setupAR(cameraConfig.facingMode).catch(() => void 0);
|
|
6671
7050
|
}
|
|
6672
7051
|
}
|
|
6673
|
-
|
|
6674
|
-
|
|
7052
|
+
}, [cameraConfig?.facingMode, cameraFacing, cleanupAR, setupAR]);
|
|
7053
|
+
React10.useEffect(() => {
|
|
7054
|
+
if (!modelPresets.find((preset) => preset.id === selectedModelId)) {
|
|
7055
|
+
setSelectedModelId(modelPresets[0]?.id ?? "");
|
|
6675
7056
|
}
|
|
6676
|
-
|
|
6677
|
-
}, [state.markerDetected]);
|
|
7057
|
+
}, [modelPresets, selectedModelId]);
|
|
6678
7058
|
React10.useEffect(() => {
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
}
|
|
6710
|
-
};
|
|
6711
|
-
initialize();
|
|
7059
|
+
if (!motionPresets.find((preset) => preset.id === selectedMotionId)) {
|
|
7060
|
+
setSelectedMotionId(motionPresets[0]?.id ?? "");
|
|
7061
|
+
}
|
|
7062
|
+
}, [motionPresets, selectedMotionId]);
|
|
7063
|
+
React10.useEffect(() => {
|
|
7064
|
+
if (audioPresets && !audioPresets.find((preset) => preset.id === selectedAudioId)) {
|
|
7065
|
+
setSelectedAudioId(audioPresets[0]?.id ?? "");
|
|
7066
|
+
}
|
|
7067
|
+
}, [audioPresets, selectedAudioId]);
|
|
7068
|
+
React10.useEffect(() => {
|
|
7069
|
+
if (typeof window === "undefined") return;
|
|
7070
|
+
if (!rendererRef.current) {
|
|
7071
|
+
setupRenderer();
|
|
7072
|
+
}
|
|
7073
|
+
if (!arToolkitSourceRef.current) {
|
|
7074
|
+
setupAR().then(() => {
|
|
7075
|
+
startRenderLoop();
|
|
7076
|
+
}).catch((err) => {
|
|
7077
|
+
const message = err instanceof Error ? err.message : "Failed to initialize AR";
|
|
7078
|
+
setError(message);
|
|
7079
|
+
setIsLoading(false);
|
|
7080
|
+
onCameraError?.(err instanceof Error ? err : new Error(message));
|
|
7081
|
+
});
|
|
7082
|
+
} else {
|
|
7083
|
+
startRenderLoop();
|
|
7084
|
+
}
|
|
7085
|
+
const resizeObserver = new ResizeObserver(resize);
|
|
7086
|
+
if (containerRef.current) {
|
|
7087
|
+
resizeObserver.observe(containerRef.current);
|
|
7088
|
+
}
|
|
6712
7089
|
return () => {
|
|
7090
|
+
resizeObserver.disconnect();
|
|
7091
|
+
cleanupAR();
|
|
7092
|
+
if (animationFrameRef.current) {
|
|
7093
|
+
cancelAnimationFrame(animationFrameRef.current);
|
|
7094
|
+
animationFrameRef.current = null;
|
|
7095
|
+
}
|
|
6713
7096
|
if (rendererRef.current) {
|
|
6714
7097
|
rendererRef.current.dispose();
|
|
7098
|
+
rendererRef.current = null;
|
|
6715
7099
|
}
|
|
6716
|
-
if (
|
|
6717
|
-
|
|
6718
|
-
const stream = arToolkitSourceRef.current.domElement.srcObject;
|
|
6719
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
6720
|
-
}
|
|
6721
|
-
arToolkitSourceRef.current.domElement?.remove();
|
|
7100
|
+
if (sceneRef.current && modelRootRef.current) {
|
|
7101
|
+
sceneRef.current.remove(modelRootRef.current);
|
|
6722
7102
|
}
|
|
6723
|
-
if (
|
|
6724
|
-
|
|
7103
|
+
if (mmdMeshRef.current) {
|
|
7104
|
+
if (mmdHelperRef.current) {
|
|
7105
|
+
mmdHelperRef.current.remove(mmdMeshRef.current);
|
|
7106
|
+
}
|
|
7107
|
+
disposeMesh(mmdMeshRef.current);
|
|
7108
|
+
mmdMeshRef.current = null;
|
|
6725
7109
|
}
|
|
7110
|
+
mmdHelperRef.current = null;
|
|
7111
|
+
audioRef.current?.pause();
|
|
7112
|
+
audioRef.current = null;
|
|
6726
7113
|
};
|
|
6727
|
-
}, [
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
checkTHREEx();
|
|
6746
|
-
},
|
|
6747
|
-
onError: (error) => {
|
|
6748
|
-
console.error("Failed to load AR.js:", error);
|
|
6749
|
-
setState((prev) => ({
|
|
6750
|
-
...prev,
|
|
6751
|
-
error: "AR.js \u52A0\u8F7D\u5931\u8D25",
|
|
6752
|
-
isLoading: false
|
|
6753
|
-
}));
|
|
6754
|
-
}
|
|
6755
|
-
}
|
|
6756
|
-
), /* @__PURE__ */ React10__default.default.createElement(
|
|
6757
|
-
"canvas",
|
|
6758
|
-
{
|
|
6759
|
-
ref: canvasRef,
|
|
6760
|
-
className: "absolute inset-0 w-full h-full",
|
|
6761
|
-
style: { display: state.arReady ? "block" : "none" }
|
|
6762
|
-
}
|
|
6763
|
-
), state.isLoading && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center bg-gray-900 text-white" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-center" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-white mx-auto mb-4" }), /* @__PURE__ */ React10__default.default.createElement("p", null, "\u6B63\u5728\u521D\u59CB\u5316 AR \u73AF\u5883..."))), state.error && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center bg-red-900 text-white" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-center max-w-md" }, /* @__PURE__ */ React10__default.default.createElement("h2", { className: "text-xl font-bold mb-4" }, "\u521D\u59CB\u5316\u5931\u8D25"), /* @__PURE__ */ React10__default.default.createElement("p", { className: "text-red-200 mb-4" }, state.error), /* @__PURE__ */ React10__default.default.createElement(
|
|
6764
|
-
"button",
|
|
6765
|
-
{
|
|
6766
|
-
onClick: () => window.location.reload(),
|
|
6767
|
-
className: "px-4 py-2 bg-red-600 hover:bg-red-700 rounded-lg transition-colors"
|
|
6768
|
-
},
|
|
6769
|
-
"\u91CD\u65B0\u52A0\u8F7D"
|
|
6770
|
-
))), state.arReady && !state.error && /* @__PURE__ */ React10__default.default.createElement(React10__default.default.Fragment, null, !state.modelPlaced && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-4 left-4 right-4 bg-black/70 text-white p-4 rounded-lg" }, /* @__PURE__ */ React10__default.default.createElement("h3", { className: "font-bold mb-2" }, "AR \u653E\u7F6E\u8BF4\u660E"), /* @__PURE__ */ React10__default.default.createElement("p", { className: "text-sm text-gray-300" }, "1. \u5141\u8BB8\u6444\u50CF\u5934\u8BBF\u95EE\u6743\u9650", /* @__PURE__ */ React10__default.default.createElement("br", null), "2. \u51C6\u5907\u4E00\u4E2A\u6761\u7801\u6807\u8BB0 (\u503C: 0) \u6216 Hiro \u6807\u8BB0\u56FE\u6848", /* @__PURE__ */ React10__default.default.createElement("br", null), "3. \u5C06\u6444\u50CF\u5934\u5BF9\u51C6\u6807\u8BB0\uFF0C\u7EFF\u8272\u7ACB\u65B9\u4F53\u5C06\u51FA\u73B0\u5728\u6807\u8BB0\u4F4D\u7F6E", /* @__PURE__ */ React10__default.default.createElement("br", null), state.markerDetected ? /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-green-400 font-bold" }, "\u2713 \u6807\u8BB0\u5DF2\u68C0\u6D4B\u5230\uFF01") : /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-yellow-400" }, "\u7B49\u5F85\u6807\u8BB0\u68C0\u6D4B..."), /* @__PURE__ */ React10__default.default.createElement("br", null), '4. \u70B9\u51FB"\u653E\u7F6E\u6A21\u578B"\u6309\u94AE\u56FA\u5B9A\u6A21\u578B\u4F4D\u7F6E')), state.showSettings && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-4 right-4 bg-black/90 text-white p-4 rounded-lg min-w-80 max-w-sm max-h-96 overflow-y-auto" }, /* @__PURE__ */ React10__default.default.createElement("h3", { className: "font-bold mb-4 text-lg" }, "\u2699\uFE0F \u8BBE\u7F6E\u9762\u677F"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "border-b border-gray-600 pb-3" }, /* @__PURE__ */ React10__default.default.createElement("h4", { className: "font-semibold mb-2 text-blue-300" }, "\u{1F4F7} \u6444\u50CF\u5934\u8BBE\u7F6E"), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u6444\u50CF\u5934\u671D\u5411"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6771
|
-
"select",
|
|
6772
|
-
{
|
|
6773
|
-
value: state.cameraFacing,
|
|
6774
|
-
onChange: (e) => handleARSettingChange("cameraFacing", e.target.value),
|
|
6775
|
-
className: "w-full px-3 py-2 bg-gray-700 rounded border border-gray-600 text-sm"
|
|
6776
|
-
},
|
|
6777
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "environment" }, "\u540E\u7F6E\u6444\u50CF\u5934"),
|
|
6778
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "user" }, "\u524D\u7F6E\u6444\u50CF\u5934")
|
|
6779
|
-
))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "border-b border-gray-600 pb-3" }, /* @__PURE__ */ React10__default.default.createElement("h4", { className: "font-semibold mb-2 text-green-300" }, "\u{1F3AF} AR \u68C0\u6D4B\u8BBE\u7F6E"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u6807\u8BB0\u7C7B\u578B"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6780
|
-
"select",
|
|
6781
|
-
{
|
|
6782
|
-
value: state.markerType,
|
|
6783
|
-
onChange: (e) => handleARSettingChange("markerType", e.target.value),
|
|
6784
|
-
className: "w-full px-3 py-2 bg-gray-700 rounded border border-gray-600 text-sm"
|
|
6785
|
-
},
|
|
6786
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "barcode" }, "\u6761\u7801 (Barcode)"),
|
|
6787
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "pattern" }, "\u56FE\u6848 (Hiro)")
|
|
6788
|
-
)), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u68C0\u6D4B\u8D28\u91CF"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6789
|
-
"select",
|
|
6790
|
-
{
|
|
6791
|
-
value: state.quality,
|
|
6792
|
-
onChange: (e) => handleARSettingChange("quality", e.target.value),
|
|
6793
|
-
className: "w-full px-3 py-2 bg-gray-700 rounded border border-gray-600 text-sm"
|
|
6794
|
-
},
|
|
6795
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "low" }, "\u4F4E\u8D28\u91CF (15fps)"),
|
|
6796
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "medium" }, "\u4E2D\u7B49\u8D28\u91CF (30fps)"),
|
|
6797
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "high" }, "\u9AD8\u8D28\u91CF (60fps)")
|
|
6798
|
-
)))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "border-b border-gray-600 pb-3" }, /* @__PURE__ */ React10__default.default.createElement("h4", { className: "font-semibold mb-2 text-purple-300" }, "\u{1F441}\uFE0F \u89C6\u89C9\u8BBE\u7F6E"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React10__default.default.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
6799
|
-
"input",
|
|
6800
|
-
{
|
|
6801
|
-
type: "checkbox",
|
|
6802
|
-
checked: state.showWireframe,
|
|
6803
|
-
onChange: (e) => setState((prev) => ({ ...prev, showWireframe: e.target.checked })),
|
|
6804
|
-
className: "mr-2"
|
|
6805
|
-
}
|
|
6806
|
-
), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-sm" }, "\u663E\u793A\u7EBF\u6846")), /* @__PURE__ */ React10__default.default.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
6807
|
-
"input",
|
|
6808
|
-
{
|
|
6809
|
-
type: "checkbox",
|
|
6810
|
-
checked: state.lightingEnabled,
|
|
6811
|
-
onChange: (e) => setState((prev) => ({ ...prev, lightingEnabled: e.target.checked })),
|
|
6812
|
-
className: "mr-2"
|
|
6813
|
-
}
|
|
6814
|
-
), /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-sm" }, "\u542F\u7528\u5149\u7167")))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "border-b border-gray-600 pb-3" }, /* @__PURE__ */ React10__default.default.createElement("h4", { className: "font-semibold mb-2 text-orange-300" }, "\u{1F3AD} \u6A21\u578B\u4E0E\u52A8\u753B"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u6A21\u578B\u9009\u62E9"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6815
|
-
"select",
|
|
6816
|
-
{
|
|
6817
|
-
value: state.selectedModel,
|
|
6818
|
-
onChange: (e) => setState((prev) => ({ ...prev, selectedModel: e.target.value })),
|
|
6819
|
-
className: "w-full px-3 py-2 bg-gray-700 rounded border border-gray-600 text-sm"
|
|
6820
|
-
},
|
|
6821
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "sphere" }, "\u{1F310} \u7403\u4F53"),
|
|
6822
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "cube" }, "\u2B1C \u7ACB\u65B9\u4F53"),
|
|
6823
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "torus" }, "\u2B55 \u5706\u73AF")
|
|
6824
|
-
)), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u52A8\u4F5C\u9009\u62E9"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6825
|
-
"select",
|
|
6826
|
-
{
|
|
6827
|
-
value: state.selectedMotion,
|
|
6828
|
-
onChange: (e) => setState((prev) => ({ ...prev, selectedMotion: e.target.value })),
|
|
6829
|
-
className: "w-full px-3 py-2 bg-gray-700 rounded border border-gray-600 text-sm"
|
|
6830
|
-
},
|
|
6831
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "idle" }, "\u{1F9D8} \u5F85\u673A"),
|
|
6832
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "dance" }, "\u{1F483} \u821E\u8E48"),
|
|
6833
|
-
/* @__PURE__ */ React10__default.default.createElement("option", { value: "wave" }, "\u{1F44B} \u6325\u624B")
|
|
6834
|
-
)), /* @__PURE__ */ React10__default.default.createElement("div", null, /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-sm font-medium mb-1" }, "\u97F3\u4E50\u9009\u62E9"), /* @__PURE__ */ React10__default.default.createElement(
|
|
6835
|
-
"select",
|
|
7114
|
+
}, [cleanupAR, onCameraError, resize, setupAR, setupRenderer, startRenderLoop]);
|
|
7115
|
+
React10.useEffect(() => {
|
|
7116
|
+
attachModelRoot(resolvedARMode);
|
|
7117
|
+
}, [attachModelRoot, resolvedARMode]);
|
|
7118
|
+
React10.useEffect(() => {
|
|
7119
|
+
if (resolvedResources) {
|
|
7120
|
+
loadMMDResources();
|
|
7121
|
+
updateAudio();
|
|
7122
|
+
} else if (modelPresets.length === 0) {
|
|
7123
|
+
const message = "No model presets configured.";
|
|
7124
|
+
setError(message);
|
|
7125
|
+
setIsLoading(false);
|
|
7126
|
+
onError?.(new Error(message));
|
|
7127
|
+
}
|
|
7128
|
+
}, [loadMMDResources, modelPresets.length, onError, resolvedResources, updateAudio]);
|
|
7129
|
+
const mirroredStyle = mirrored ? { transform: "scaleX(-1)" } : void 0;
|
|
7130
|
+
return /* @__PURE__ */ React10__default.default.createElement(
|
|
7131
|
+
"div",
|
|
6836
7132
|
{
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
7133
|
+
ref: containerRef,
|
|
7134
|
+
className: clsx.clsx("relative w-full h-full overflow-hidden bg-black", className),
|
|
7135
|
+
style
|
|
6840
7136
|
},
|
|
6841
|
-
/* @__PURE__ */ React10__default.default.createElement("
|
|
6842
|
-
/* @__PURE__ */ React10__default.default.createElement("
|
|
6843
|
-
/* @__PURE__ */ React10__default.default.createElement("
|
|
6844
|
-
|
|
6845
|
-
"
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
7137
|
+
/* @__PURE__ */ React10__default.default.createElement("div", { ref: videoContainerRef, className: "absolute inset-0", style: mirroredStyle }),
|
|
7138
|
+
/* @__PURE__ */ React10__default.default.createElement("canvas", { ref: canvasRef, className: "absolute inset-0 w-full h-full", style: mirroredStyle }),
|
|
7139
|
+
isLoading && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center bg-black/70 text-white z-20" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-center" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "h-10 w-10 animate-spin rounded-full border-b-2 border-white mx-auto mb-3" }), /* @__PURE__ */ React10__default.default.createElement("div", null, "Initializing AR..."))),
|
|
7140
|
+
error && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center bg-red-950/80 text-white z-20" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-center max-w-sm px-4" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-lg font-semibold mb-2" }, "AR Error"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-sm text-red-200" }, error))),
|
|
7141
|
+
arReady && !error && /* @__PURE__ */ React10__default.default.createElement(React10__default.default.Fragment, null, resolvedARMode !== "overlay" /* Overlay */ && !modelPlaced && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-4 left-4 right-4 bg-black/70 text-white p-3 rounded-lg text-sm z-10" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "font-semibold mb-1" }, "Marker Placement"), /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-gray-200" }, 'Align the marker in view, then tap "', placementText, '" to place the model.'), /* @__PURE__ */ React10__default.default.createElement("div", { className: "mt-2" }, markerDetected ? /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-green-400" }, "Marker detected") : /* @__PURE__ */ React10__default.default.createElement("span", { className: "text-yellow-400" }, "Waiting for marker..."))), /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-4 right-4 flex items-center space-x-2 z-10" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
7142
|
+
"span",
|
|
7143
|
+
{
|
|
7144
|
+
className: clsx.clsx("h-2.5 w-2.5 rounded-full", cameraReady ? "bg-green-400" : "bg-red-400"),
|
|
7145
|
+
title: "Camera"
|
|
7146
|
+
}
|
|
7147
|
+
), /* @__PURE__ */ React10__default.default.createElement(
|
|
7148
|
+
"span",
|
|
7149
|
+
{
|
|
7150
|
+
className: clsx.clsx("h-2.5 w-2.5 rounded-full", arReady ? "bg-green-400" : "bg-red-400"),
|
|
7151
|
+
title: "AR"
|
|
7152
|
+
}
|
|
7153
|
+
), /* @__PURE__ */ React10__default.default.createElement(
|
|
7154
|
+
"span",
|
|
7155
|
+
{
|
|
7156
|
+
className: clsx.clsx("h-2.5 w-2.5 rounded-full", markerDetected ? "bg-blue-400" : "bg-gray-400"),
|
|
7157
|
+
title: "Marker"
|
|
7158
|
+
}
|
|
7159
|
+
)), /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute bottom-4 left-4 right-4 flex justify-center gap-3 z-10" }, /* @__PURE__ */ React10__default.default.createElement(
|
|
7160
|
+
"button",
|
|
7161
|
+
{
|
|
7162
|
+
onClick: () => setSettingsVisible((prev) => !prev),
|
|
7163
|
+
className: "px-4 py-2 rounded-lg bg-gray-700 text-white hover:bg-gray-600"
|
|
6855
7164
|
},
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
}
|
|
6867
|
-
if (markerRootRef.current) {
|
|
6868
|
-
markerRootRef.current.visible = true;
|
|
6869
|
-
}
|
|
6870
|
-
setState((prev) => ({
|
|
6871
|
-
...prev,
|
|
6872
|
-
modelPlaced: false,
|
|
6873
|
-
markerDetected: false,
|
|
6874
|
-
selectedModel: "sphere",
|
|
6875
|
-
selectedMotion: "idle",
|
|
6876
|
-
selectedAudio: "none"
|
|
6877
|
-
}));
|
|
7165
|
+
"Settings"
|
|
7166
|
+
), resolvedARMode !== "overlay" /* Overlay */ && !modelPlaced && /* @__PURE__ */ React10__default.default.createElement(
|
|
7167
|
+
"button",
|
|
7168
|
+
{
|
|
7169
|
+
onClick: placeModel,
|
|
7170
|
+
disabled: !markerDetected,
|
|
7171
|
+
className: clsx.clsx(
|
|
7172
|
+
"px-5 py-2 rounded-lg text-white",
|
|
7173
|
+
markerDetected ? "bg-emerald-600 hover:bg-emerald-500" : "bg-gray-500"
|
|
7174
|
+
)
|
|
6878
7175
|
},
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
},
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
"
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
7176
|
+
placementText
|
|
7177
|
+
), modelPlaced && /* @__PURE__ */ React10__default.default.createElement(
|
|
7178
|
+
"button",
|
|
7179
|
+
{
|
|
7180
|
+
onClick: removeModel,
|
|
7181
|
+
className: "px-5 py-2 rounded-lg text-white bg-orange-600 hover:bg-orange-500"
|
|
7182
|
+
},
|
|
7183
|
+
"Reset"
|
|
7184
|
+
)), settingsVisible && /* @__PURE__ */ React10__default.default.createElement("div", { className: "absolute top-16 right-4 bg-black/80 text-white p-4 rounded-lg w-64 space-y-3 z-10" }, /* @__PURE__ */ React10__default.default.createElement("div", { className: "text-sm font-semibold" }, "AR Settings"), /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs text-gray-300" }, "Model", /* @__PURE__ */ React10__default.default.createElement(
|
|
7185
|
+
"select",
|
|
7186
|
+
{
|
|
7187
|
+
value: selectedModelId,
|
|
7188
|
+
onChange: (event) => {
|
|
7189
|
+
setOverrideResources(null);
|
|
7190
|
+
setSelectedModelId(event.target.value);
|
|
7191
|
+
},
|
|
7192
|
+
className: "mt-1 w-full bg-gray-700 text-white text-sm rounded px-2 py-1"
|
|
7193
|
+
},
|
|
7194
|
+
modelPresets.map((preset) => /* @__PURE__ */ React10__default.default.createElement("option", { key: preset.id, value: preset.id }, preset.name))
|
|
7195
|
+
)), /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs text-gray-300" }, "Motion", /* @__PURE__ */ React10__default.default.createElement(
|
|
7196
|
+
"select",
|
|
7197
|
+
{
|
|
7198
|
+
value: selectedMotionId,
|
|
7199
|
+
onChange: (event) => {
|
|
7200
|
+
setOverrideResources(null);
|
|
7201
|
+
setSelectedMotionId(event.target.value);
|
|
7202
|
+
},
|
|
7203
|
+
className: "mt-1 w-full bg-gray-700 text-white text-sm rounded px-2 py-1"
|
|
7204
|
+
},
|
|
7205
|
+
motionPresets.map((preset) => /* @__PURE__ */ React10__default.default.createElement("option", { key: preset.id, value: preset.id }, preset.name))
|
|
7206
|
+
)), audioPresets && audioPresets.length > 0 && /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs text-gray-300" }, "Audio", /* @__PURE__ */ React10__default.default.createElement(
|
|
7207
|
+
"select",
|
|
7208
|
+
{
|
|
7209
|
+
value: selectedAudioId,
|
|
7210
|
+
onChange: (event) => {
|
|
7211
|
+
setOverrideResources(null);
|
|
7212
|
+
setSelectedAudioId(event.target.value);
|
|
7213
|
+
},
|
|
7214
|
+
className: "mt-1 w-full bg-gray-700 text-white text-sm rounded px-2 py-1"
|
|
7215
|
+
},
|
|
7216
|
+
audioPresets.map((preset) => /* @__PURE__ */ React10__default.default.createElement("option", { key: preset.id, value: preset.id }, preset.name))
|
|
7217
|
+
)), /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs text-gray-300" }, "AR Mode", /* @__PURE__ */ React10__default.default.createElement(
|
|
7218
|
+
"select",
|
|
7219
|
+
{
|
|
7220
|
+
value: resolvedARMode,
|
|
7221
|
+
onChange: (event) => {
|
|
7222
|
+
const next = event.target.value;
|
|
7223
|
+
if (!arMode) {
|
|
7224
|
+
setInternalARMode(next);
|
|
7225
|
+
}
|
|
7226
|
+
attachModelRoot(next);
|
|
7227
|
+
onARModeChange?.(next);
|
|
7228
|
+
},
|
|
7229
|
+
className: "mt-1 w-full bg-gray-700 text-white text-sm rounded px-2 py-1"
|
|
7230
|
+
},
|
|
7231
|
+
/* @__PURE__ */ React10__default.default.createElement("option", { value: "overlay" /* Overlay */ }, "Overlay"),
|
|
7232
|
+
/* @__PURE__ */ React10__default.default.createElement("option", { value: "world-fixed" /* WorldFixed */ }, "World Fixed")
|
|
7233
|
+
)), /* @__PURE__ */ React10__default.default.createElement("label", { className: "block text-xs text-gray-300" }, "Camera", /* @__PURE__ */ React10__default.default.createElement(
|
|
7234
|
+
"select",
|
|
7235
|
+
{
|
|
7236
|
+
value: cameraFacing,
|
|
7237
|
+
onChange: (event) => {
|
|
7238
|
+
const next = event.target.value;
|
|
7239
|
+
setCameraFacing(next);
|
|
7240
|
+
cleanupAR();
|
|
7241
|
+
setupAR(next).catch(() => void 0);
|
|
7242
|
+
},
|
|
7243
|
+
className: "mt-1 w-full bg-gray-700 text-white text-sm rounded px-2 py-1"
|
|
7244
|
+
},
|
|
7245
|
+
/* @__PURE__ */ React10__default.default.createElement("option", { value: "environment" }, "Back"),
|
|
7246
|
+
/* @__PURE__ */ React10__default.default.createElement("option", { value: "user" }, "Front")
|
|
7247
|
+
))))
|
|
7248
|
+
);
|
|
6905
7249
|
});
|
|
6906
|
-
|
|
7250
|
+
MMDARApp.displayName = "MMDARApp";
|
|
6907
7251
|
|
|
6908
|
-
// src/mmd/ar/
|
|
6909
|
-
var
|
|
6910
|
-
|
|
6911
|
-
ARMode2["WorldFixed"] = "world-fixed";
|
|
6912
|
-
return ARMode2;
|
|
6913
|
-
})(ARMode || {});
|
|
7252
|
+
// src/mmd/ar/MMDARPlayer.tsx
|
|
7253
|
+
var MMDARPlayer = MMDARApp;
|
|
7254
|
+
MMDARPlayer.displayName = "MMDARPlayer";
|
|
6914
7255
|
|
|
6915
7256
|
// src/mmd/fx/HLSLToGLSLConverter.ts
|
|
6916
7257
|
var HLSLToGLSLConverter = class {
|
|
@@ -9015,6 +9356,7 @@ exports.HistoryPanel = HistoryPanel;
|
|
|
9015
9356
|
exports.LoadingOverlay = LoadingOverlay;
|
|
9016
9357
|
exports.LoadingScreen = LoadingScreen;
|
|
9017
9358
|
exports.LoopConfirmDialog = LoopConfirmDialog;
|
|
9359
|
+
exports.MMDARApp = MMDARApp;
|
|
9018
9360
|
exports.MMDARPlayer = MMDARPlayer;
|
|
9019
9361
|
exports.MMDLightingDebugPanel = MMDLightingDebugPanel;
|
|
9020
9362
|
exports.MMDMusicPlayer = MMDMusicPlayer;
|
|
@@ -9023,8 +9365,10 @@ exports.MMDPlayerEnhanced = MMDPlayerEnhanced;
|
|
|
9023
9365
|
exports.MMDPlayerEnhancedDebugInfo = MMDPlayerEnhancedDebugInfo;
|
|
9024
9366
|
exports.MMDPlaylist = MMDPlaylist;
|
|
9025
9367
|
exports.MMDPlaylistDebugInfo = MMDPlaylistDebugInfo;
|
|
9368
|
+
exports.MMDUploadPanel = MMDUploadPanel;
|
|
9026
9369
|
exports.MMDVisualNovel = MMDVisualNovel;
|
|
9027
9370
|
exports.MMDVisualNovelWithSelector = MMDVisualNovelWithSelector;
|
|
9371
|
+
exports.MMD_UPLOAD_CONFIGS = MMD_UPLOAD_CONFIGS;
|
|
9028
9372
|
exports.ModelSelectorSettings = ModelSelectorSettings;
|
|
9029
9373
|
exports.MultiFXAdapter = MultiFXAdapter;
|
|
9030
9374
|
exports.MusicControls = MusicControls;
|