Skip to content

Commit 0ea0c77

Browse files
authored
fix(model-profiler): correct VRM skeleton detection (Project-N-E-K-O#944)
* feat(model-manager): add Live3D rotation and camera pitch controls * fix(model-profiler): correct VRM skeleton detection 修复模型管理页性能分析器对 VRMManager 的识别逻辑,避免把 VRM 误判为 MMD。\n\n修复 VRM 快照读取 currentModel 结构的问题,改为从真实的 currentModel.vrm 中获取 humanoid 与场景信息。\n\n调整模型管理页分析器优先选择当前可见且已加载的管理器,并补齐 VRM 骨骼调试可视化支持。 * Revert "feat(model-manager): add Live3D rotation and camera pitch controls" This reverts commit 815dd93.
1 parent 92191c3 commit 0ea0c77

3 files changed

Lines changed: 44 additions & 12 deletions

File tree

static/model-profiler-ui.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,9 @@ class ModelProfilerUI {
283283
_toggleDebugHelper(type, btn) {
284284
const manager = this.getManager?.();
285285
if (!manager) return;
286-
const mmd = manager.currentModel;
287-
if (!mmd || !mmd.mesh) return;
286+
const currentModel = manager.currentModel;
287+
const mmd = currentModel?.mesh ? currentModel : null;
288+
const vrm = currentModel?.vrm || (currentModel?.scene && !currentModel?.mesh ? currentModel : null);
288289
const scene = manager.scene;
289290
if (!scene) return;
290291

@@ -305,6 +306,10 @@ class ModelProfilerUI {
305306
let helper = null;
306307
try {
307308
if (type.startsWith('physics-')) {
309+
if (!mmd || !mmd.mesh) {
310+
console.warn('[Profiler] 当前模型不支持物理刚体可视化');
311+
return;
312+
}
308313
const modeMap = { 'physics-kinematic': 0, 'physics-dynamic': 1, 'physics-mixed': 2 };
309314
const colorMap = { 'physics-kinematic': 0xFF6B35, 'physics-dynamic': 0xE040FB, 'physics-mixed': 0x448AFF };
310315
helper = this._createPhysicsWireframes(mmd, modeMap[type], colorMap[type]);
@@ -318,7 +323,12 @@ class ModelProfilerUI {
318323
} else if (type === 'skeleton') {
319324
const THREE = window.THREE;
320325
if (THREE?.SkeletonHelper) {
321-
helper = new THREE.SkeletonHelper(mmd.mesh);
326+
const skeletonTarget = mmd?.mesh || vrm?.scene || null;
327+
if (!skeletonTarget) {
328+
console.warn('[Profiler] 当前模型未找到可用骨骼节点');
329+
return;
330+
}
331+
helper = new THREE.SkeletonHelper(skeletonTarget);
322332
helper.visible = true;
323333
} else {
324334
console.warn('[Profiler] SkeletonHelper 不可用');

static/model-profiler.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,16 @@ class ModelProfiler {
257257
if (!manager) return null;
258258

259259
// 检测模型类型
260-
const isMMD = manager.constructor?.name === 'MMDManager' || !!manager.core;
261-
const isVRM = manager.constructor?.name === 'VRMManager' || !!manager._cursorFollow;
260+
const ctorName = manager.constructor?.name || '';
261+
const currentModel = manager.currentModel || null;
262+
const isVRM = ctorName === 'VRMManager' || !!manager._cursorFollow || !!currentModel?.vrm;
263+
const isMMD = ctorName === 'MMDManager' || !!currentModel?.mesh;
262264

263265
let snap;
264-
if (isMMD) {
265-
snap = this._snapshotMMD(manager);
266-
} else if (isVRM) {
266+
if (isVRM) {
267267
snap = this._snapshotVRM(manager);
268+
} else if (isMMD) {
269+
snap = this._snapshotMMD(manager);
268270
} else {
269271
snap = { type: 'unknown', error: '无法识别的管理器类型' };
270272
}
@@ -411,10 +413,11 @@ class ModelProfiler {
411413
return snap;
412414
}
413415
snap.loaded = true;
416+
snap.name = model.url || model.name || '(unknown)';
414417

415418
// VRM 模型信息
416-
const vrm = model;
417-
const scene = vrm.scene || vrm;
419+
const vrm = model.vrm || model;
420+
const scene = vrm.scene || model.scene || vrm;
418421

419422
// 遍历场景统计几何信息
420423
let totalVertices = 0;

templates/model_manager.html

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,14 +645,33 @@ <h3 data-i18n="live2d.mmdAnimation.deleteAnimationTitle">删除已导入VMD动
645645
document.addEventListener('DOMContentLoaded', function() {
646646
const mount = document.getElementById('profiler-mount');
647647
if (mount && typeof ModelProfilerUI !== 'undefined') {
648+
const isVisible = function(el) {
649+
return !!(el && el.style.display !== 'none' && !el.classList.contains('hidden'));
650+
};
651+
const getActiveManager = function() {
652+
const vrmManager = window.vrmManager || null;
653+
const mmdManager = window.mmdManager || null;
654+
const vrmContainer = document.getElementById('vrm-container');
655+
const mmdContainer = document.getElementById('mmd-container');
656+
657+
const vrmReady = !!vrmManager?.currentModel?.vrm;
658+
const mmdReady = !!mmdManager?.currentModel?.mesh;
659+
660+
if (isVisible(vrmContainer) && vrmReady) return vrmManager;
661+
if (isVisible(mmdContainer) && mmdReady) return mmdManager;
662+
if (vrmReady) return vrmManager;
663+
if (mmdReady) return mmdManager;
664+
return vrmManager || mmdManager || null;
665+
};
666+
648667
window._profilerUI = new ModelProfilerUI({
649668
container: mount,
650669
collapsed: true,
651670
getManager: function() {
652-
return window.mmdManager || window.vrmManager || null;
671+
return getActiveManager();
653672
},
654673
getRenderer: function() {
655-
var mgr = window.mmdManager || window.vrmManager;
674+
var mgr = getActiveManager();
656675
return mgr ? mgr.renderer : null;
657676
}
658677
});

0 commit comments

Comments
 (0)